ウィンドウを作らないでGDIを使って描画する.

メモリを確保→描画先としてセット

hBitmap = CreateDIBSection(::GetDC(NULL), &bmi, DIB_RGB_COLORS, (void**)&pixel, NULL, NULL);
HDC memDC =CreateCompatibleDC(::GetDC(NULL));
HGDIOBJ oldBitmap = SelectObject(memDC,hBitmap);

pixelは,DIBのメモリが保存されるポインタが保存される.
このメモリはプログラムで解放する必要はなく,hBitmapを破棄したときに解放される.
そして,次にGetDCで得たデバイスコンテキスト互換のメモリデバイスコンテキストを作成し,このメモリデバイスコンテキストに作成したhBitmapに結びつける.
この::GetDC(NULL)が,ずっと引っかかっていたのだ.
普通は,ウィンドウがあるので,そのウィンドウをのハンドルを使うんだろうが・・・.
ドキュメントによると,
-引用-
デバイスコンテキストの取得対象となるウィンドウのハンドルを指定します。NULL を指定すると、GetDC は画面全体を表すデバイスコンテキストを取得します。
-引用-
だそうだ.
ということは,ビットマップハンドルも,ビットマップハンドルに結びつけるメモリデバイスコンテキストも,画面全体のデバイスコンテキスト互換ということなのか・・・.
となるとなぁ・・・.デバイスコンテキスト互換というのは,何が互換なんだろう・・・・?
まぁ,とかく,だいたいそういうことだ.

補足情報

画面全体のデバイスコンテキストは,以下のコードでも取得できる.

HDC hdc_disp = CreateDC("DISPLAY", NULL, NULL, NULL);

ただし,

DeleteDC(hdc_disp);

として,取得したDCを明示的に破棄する必要がある.
※(さ)さんのコメントを追記しました.

書いてみる

char *msg = "GDIのテスト";
::TextOut(memDC,0,0,msg,strlen(msg));

これで,メモリビットマップに「GDIのテスト」という文字が描画される.ウマーーー.

後始末

SelectObject(memDC,oldBitmap);
DeleteObject(hBitmap);

デバイスコンテキストに結びつけたhBitmapを一応元に戻しておく.
戻し方は,SelectObjectで返ってくるハンドルを入れるだけでよい.返ってくるハンドルは,SelectObjectをする前のハンドルなのである.
後は,メモリビットマップをDeleteObjectで,メモリビットマップを解放する.