Windowsプログラミング リージョンについて

このQ&Aのポイント
  • Windowsプログラミングでリージョンについて学びましょう。
  • CombineRgn関数やGetClipRgn関数についても理解しましょう。
  • DeleteObject関数によるリージョンの削除方法も確認しましょう。
回答を見る
  • ベストアンサー

Windowsプログラミング リージョンについて

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; PAINTSTRUCT ps; HRGN hRgn1, hRgn2; RECT rect; switch(msg){ case WM_DESTROY: PostQuitMessage(0); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); hRgn1 = CreateEllipticRgn(10, 10, 100, 100); hRgn2 = CreateEllipticRgn(50, 50, 200, 150); CombineRgn(hRgn1, hRgn1, hRgn2, RGN_OR); SelectClipRgn(hdc, hRgn1); GetClipBox(hdc, &rect); GetClipRgn(hdc, hRgn2); SelectClipRgn(hdc, NULL); DeleteObject(hRgn1); Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom); FillRgn(hdc, hRgn2, GetStockObject(BLACK_BRUSH)); DeleteObject(hRgn2); EndPaint(hwnd, &ps); return 0; } return DefWindowProc(hwnd, msg, wp, lp); } リージョンというものがよく理解できません。 なぜCombineRgnの第一引数のリージョンが存在していないといけないのですか? DeleteObject(hRgn1);でhRgn1をDeleteしてるのにhRgn2が使えるのは なぜですか?  GetClipRgnで設定されたリージョンを取得しているようなんですか、このリージョンは領域の情報の共有ではなく、たんなる 領域の情報のコピーなのですか? DeleteObjectでDeleteしているhRgn1, hRgn2はどのリージョン(どのリージョンといった方がいいのかわかりませんが)を削除しているのか分かりません。 あと上記のソースとは関係ないのですが hRgn1 = CreateEllipticRgn(10, 10, 100, 100); hRgn2 = CreateEllipticRgn(50, 50, 200, 150); CombineRgn(hRgn1, hRgn1, hRgn2, RGN_OR); DeleteObject(hRgn1); DeleteObject(hRgn2); ←もしかしてこれは不要? としたとき DeleteObject(hRgn2);は不要なのでしょうか? 超初心者な質問ですみません。質問の仕方へたですみません。 分かる人お願いします。

  • sizum
  • お礼率77% (7/9)

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

『新たに』というより演算結果を格納するための受け皿です 新たにハンドルを作成する機能まで盛り込んでいないためあらかじめハンドルを作成しておかないといけない訳です GetClipRgnは現在アプリケーションによって設定されているリージョン領域を取得する関数です 設定は SelectClipRgnで行います このあたりの解説は VC++付属の MSDNなどで確認可能ですよ

sizum
質問者

お礼

ありがとうございました^^。

その他の回答 (1)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

CombineRgnの第1引数ですが これは演算結果を受け取るためのハンドルだからです 2つのリージョンの演算結果を まったく別のリージョンに設定することも可能なのです DeleteObjectは 引数に与えられたハンドルに関連付けされたオブジェクトを削除します hRgn1とhRgn2は別空間に配置されていますので hRgn1にhRgn2の領域が含まれていても hRgn1でアクセスしているなら操作可能です 最後の別件ですが 必要です CreateEllipticRgnで作成したハンドルと関連するオブジェクトは必ず削除するようにしましょう 繰り返し実行すると リソースを食いつぶしてしまい最悪の場合Windwosが不安定になり再起動をさせられる羽目になる可能性があります

sizum
質問者

補足

CombineRgnはあらたにオブジェクトを生成するのではなく、あらたに結合した演算結果を格納する(こうゆう表現でいいのか分かりませんが)関数みたいな感じで覚えればいいのでしょうか? GetClipRgnも現在設定されているリージョンの演算結果を受け取るような考え方でいいのでしょうか?

関連するQ&A

  • フォントの指定 猫でもわかるwindowsプログラミングより

    猫でもわかるwindowsプログラミングの本で勉強している学生なんですが、第2章の2.4フォントの指定のところでプログラムを打ち込んでコンパイルしたのですがなぜか識別子が見つかりませんというエラーがでてコンパイルできません。どなたかわかる方お願いします。 一応プログラム(CALLBACK関数と論理フォント作成の関数のみ)↓ //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){ static HFONT hFont1, hFont2, hFont3; PAINTSTRUCT ps; HDC hdc; char *szName1 = "○○"; char *szName2 = "▲▲"; switch (msg) { case WM_CREATE: hFont1 = MyCreateFont(40, SHIFTJIS_CHARSET, "HG行書体"); hFont2 = MyCreateFont(40, ANSI_CHARSET, "Fraktur JS"); hFont3 = MyCreateFont(40, SHIFTJIS_CHARSET, "MS 明朝"); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); SelectObject(hdc, hFont1); TextOut(hdc, 0, 0, (LPCTSTR)szName1, (int)strlen(szName1)); SelectObject(hdc, hFont2); TextOut(hdc, 0, 60, (LPCTSTR)szName2, (int)strlen(szName2)); SelectObject(hdc, hFont3); TextOut(hdc, 0, 120, (LPCTSTR)szName1, (int)strlen(szName1)); EndPaint(hWnd, &ps); break; case WM_DESTROY: DeleteObject(hFont1); DeleteObject(hFont2); DeleteObject(hFont3); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } //論理フォントの作成 HFONT MyCreateFont(int nHeight, DWORD dwCharSet, LPCTSTR lpName){ return(CreateFont(nHeight, 0, 0, 0, FW_DONTCARE. FALSE, FALSE, FALSE, dwCharSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, lpName)); } エラー内容↓ MyCreateFontの識別子が見つかりません。 論理フォントの関数のFALSEの値が構文エラーで参照できない。

  • DeleteObjectについて(初心者です)

    今こちらのサイトを参考に、APIを学んでいるものです。 http://wisdom.sakura.ne.jp/system/winapi/win32/win26.html 質問させて頂きますのはここの部分です。 LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) { HDC hdc; static LOGPEN lopnPen; PAINTSTRUCT ps; switch (msg) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_CREATE: lopnPen.lopnStyle = PS_SOLID; lopnPen.lopnWidth.x = 5; lopnPen.lopnColor = 0XFF; return 0; case WM_PAINT: hdc = BeginPaint(hwnd , &ps); SelectObject(hdc , CreatePenIndirect(&lopnPen)); Ellipse(hdc , 10 , 10 , 200 , 50); DeleteObject(SelectObject(hdc , GetStockObject(WHITE_BRUSH))); EndPaint(hwnd , &ps); return 0; } return DefWindowProc(hwnd , msg , wp , lp); } 一度yahoo知恵袋にて質問したのですが、別の面で少し疑問が残ったのでここでもう一度質問させて頂きます。 SelectObjectは引数で渡されたオブジェクトを選択中にし、返り値として以前に選択していたオブジェクトを返すという回答がありましたが、それならば DeleteObject(SelectObject(hdc , GetStockObject(WHITE_BRUSH))); のGetStockObjectの引数WHITE_BRUSHを別のもの(例えばBLACK_PEN)に置き換えても、返り値は以前選択していたオブジェクトのままなので何も相違ないはずですよね? 当方理解もままならない初心者ですから盛大な勘違いをしているかもしれません。 分かる方、どうかご教授お願いします。

  • LPTSTR型の変数に文字を格納

    LPTSTR型の変数に文字を格納 現在C言語でWindowsプログラミングを学習しています。 LPTSTR 型の変数にキーボードから入力されて1文字づつ格納したいのですが、 下記のコードであればうまくいきません。 自分がTCHARやLPTSTRのことを根本から理解できていないのが原因だと思うのですが。 LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) { static LPTSTR buffer; HDC hdc; PAINTSTRUCT ps; switch(msg){ case WM_CHRAR: *buffer++=(TCHAR)wp; InvalidateRect(hWnd,NULL,TRUE); return 0; case WM_PRINT: hdc=BeginPaint(hWnd,&ps); DrawText(hdc,buffer,-1,&rc,DT_WORDBREAK); EndPaint(hWnd,&ps); return 0; ・ ・ ・ ・

  • 猫でもわかるWindowsプログラミングの5.2タイピングソフトのプログラムについて

    猫でもわかるWindowsプログラミング第3版の5.2タイピングソフトのプログラムなのですが、 本のプログラムをそのまま書くと、タイプミス!の分岐にはいらないんですが、これは本が間違ってるんでしょうか? 付属のCD-ROMのプログラム(本の方とは少し違う)は正しく動いているようですが、 本に書いてある方がなぜ上手くいかないのかが理解できません。 もし本が間違えているなら、どこが間違っているのか教えていただけると助かります。 下のコードは本に書いてあった方のウィンドウプロージャ部を写したものです。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; PAINTSTRUCT ps; MMTIME mm; switch (msg) { case WM_CREATE: srand((unsigned)time(NULL)); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); TextOut(hdc, 0, 0, szMondai, lstrlen(szMondai)); TextOut(hdc, 0, 40, szInput, lstrlen(szInput)); if(bSeikai) SetTextColor(hdc, RGB(0,0,0)); else SetTextColor(hdc, RGB(255,0,0)); TextOut(hdc,0,80,szCheck,lstrlen(szCheck)); EndPaint(hWnd, &ps); break; case WM_CHAR: if(wp == VK_SPACE && !bStart) { bStart = TRUE; TypeStart(hWnd); break; } if(bStart == FALSE) return DefWindowProc(hWnd, msg, wp, lp); if(wp == VK_ESCAPE) { lstrcpy(szMondai, TEXT("")); lstrcpy(szInput, TEXT("")); lstrcpy(szCheck, TEXT("")); InvalidateRect(hWnd, NULL, TRUE); bStart = FALSE; break; } wsprintf(szInput, TEXT("あなたの入力=\"%c\""), (int)wp); if(szMondai[6] == szInput[14]) { bSeikai = TRUE; mm.wType = TIME_MS; timeGetSystemTime(&mm, sizeof(MMTIME)); dwEnd = mm.u.ms; wsprintf(szCheck, TEXT("反応時間[%dミリ秒]"), dwEnd - dwStart); TypeStart(hWnd); } else { bSeikai = FALSE; MessageBeep(MB_OK); lstrcpy(szCheck, TEXT("タイプミス!")); } InvalidateRect(hWnd, NULL, TRUE); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp,lp)); } return 0; } int TypeStart(HWND hWnd) { int n; MMTIME mm; n = rand() % 26; wsprintf(szMondai, TEXT("問題=\"%c\""), 'a' + n); mm.wType = TIME_MS; timeGetSystemTime(&mm, sizeof(MMTIME)); dwStart = mm.u.ms; InvalidateRect(hWnd, NULL, TRUE); return 0; }

  • WM_PAINT

    WM_PAINT について教えてほしいのですが、 WM_PAINTがシステムから発行されるタイミングとして、 クライアント領域に無効領域がある時 UpdateWindow()を呼び出した時 InvalidateRect()を呼び出した時があると思いますが 例えば LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM) { LPCTSTR  Str = TEXT("Kitty"); switch (msg) { case WM_CREATE:    hdc = GetDC(hwnd);    SetTextColor(hdc , RGB(255, 0 , 0));    ReleaseDC(hwnd , hdc);    return 0; case WM_PAINT:    hdc = BeginPaint(hwnd , &ps);    TextOut(hdc, 10 , 10 , Str, lstrlen(Str));    EndPaint(hwnd , &ps);    return 0; } return DefWindowProc(hwnd , msg , wp , lp); } の場合, WM_PAINTはどのタイミングでシステムから呼び出されるんですか? WinMain()でUpdateWindow()もInvalidateRect()もつかっていないのですが。 いつシステムから送られるかご教授をお願いします。

  • WindowsSDKのCALLBACK内について

    猫でも分かるWindowsSDKを参考にして、とりあえずウィンドウプロシージャの関数内を下のようにしてプログラムを組んでみました。 //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_CREATE: break; case WM_TIMER: break; case WM_PAINT: break; case WM_COMMAND: break; case WM_CLOSE: SendMessage(hWnd, WM_DESTROY, wp, lp); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; } しかし、これで何もないWindow表示をさせるとCPU使用率が80%くらいまで跳ね上がります。 調べてみたところcase WM_PAINT:を削ったらCPU使用率が下がりました。 普通にクライアント領域に文字を表示したり画像を表示したりするだけだったら、それほどCPU使用率が上がらないのに、上のようにあらかじめ用意しておいたらCPU使用率が跳ね上がるのは何故でしょうか。 まだ勉強したてでレベルの低い質問でしたらすみません。

  • BitBlt関数について教えてください

    よろしくお願いします。 画像を読み込むための、BitBlt関数について、色々調べてみたのですが、どうしても分からない記述が2つあります。ご指導、アドバイスをお願いします。 1、サンプルのソースを参考にしているのですが、BitBlt関数の第2、第3の記述の意味として、 『PAINTSTRUCT構造体のポインタpsが、左隅上、を参照している』と解釈したのですが、第4、第5引数の、-(引く)の意味が理解できません。 2、画像を2種類表示するためメニューに、『オプション1とオプション2』を作り、オプション1はコピー元と同じ画像を表示、 オプション2は、ラスタオペレーションを選択可能にして、選択した画像を表示すると言うものですが、DWORD dwRop; を宣言し『第9引数をNOTSRCCOPY』として、二つ目の画像を表示する case文に dwRop = NOTSRCCOPY; を追加したのですがうまく行きません。多分 『dwRop』の使い方に問題があるのかと思うのですが、うまく表示されません。 因みに、 BitBlt関数の第9引数が『SRCCOPY』の時は、正常に2種類の画像が表示されます。 /*ウィンドウプロシージャ*/  LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)  { HDC hdc;  DWORD dwRop; //追加した  PAINTSTRUCT ps;  HBITMAP hBmp;  HDC hdc_memx;  switch(msg){  case WM_CREATE:  hdc = GetDC(hWnd);  hBmp = LoadBitmap(hInst, "MYBMP1");  if(hBmp == NULL){  MessageBox(hWnd, "画像1のロードに失敗しました", "エラー",  MB_OK | MB_ICONWARNING);  return 0;  }  hdc_mem1 = CreateCompatibleDC(hdc);  SelectObject(hdc_mem1, hBmp);  DeleteObject(hBmp);  hBmp = LoadBitmap(hInst, "MYBMP2");  if(hBmp == NULL){   MessageBox(hWnd, "画像2のロードに失敗しました", "エラー",   MB_OK | MB_ICONWARNING);  return 0;  } hdc_mem2 = CreateCompatibleDC(hdc);  SelectObject(hdc_mem2, hBmp);  DeleteObject(hBmp);  ReleaseDC(hWnd, hdc);  break;  case WM_PAINT:  BeginPaint(hWnd, &ps);  if(show_no == 1) hdc_memx = hdc_mem1;  if(show_no == 2) hdc_memx = hdc_mem2;  BitBlt(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, hdc_memx, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);  // PATCOPYにして,IDM_ANIME2に、dwRop=NOTSRCCOPY //を追加しても変更されないし、画像の表示が出来ない EndPaint(hWnd, &ps);  break; case WM_COMMAND: switch (LOWORD(wp)){ case IDM_ANIME1: show_no = 1;      //dwRop = SRCCOPY //追加したが変化なし InvalidateRect(hWnd, NULL, TRUE); break;  case IDM_ANIME2: show_no = 2; //dwRop = NOTSRCCOPY; //追加したが変化なし InvalidateRect(hWnd, NULL, TRUE); break;  case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0); break; } break;  case WM_DESTROY: DeleteDC(hdc_mem1); DeleteDC(hdc_mem2); PostQuitMessage(0); break;  default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }

  • 画像を切り替えるプログラムで悩んでいます。

    C言語で、ビットマップを『2枚』表示した後、メニューの選択により、どちらかの画像だけを表示したいのです、色々試して見たのですが、うまく行きません。ヒント、アドバイスをお願いします。 本当は『2枚』だけでなく、スキャンして、保存した画像を全て表示したいのですが、まだその方法が出来ません。 1、グローバルな変数として、   HDC hdc_mem1, hdc_mem2;//2種類のメモリデバイスコンテキストハ  ンドルを格納  int show_no = 1;//画像選択のための変数1で初期化 2、/*ウィンドウプロシージャ*/ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; static DWORD dwRop;   PAINTSTRUCT ps; HBITMAP hBmp; HDC hdc_memx; switch(msg){ case WM_CREATE: hdc = GetDC(hWnd); hdc_mem1, hdc_mem2; dwRop = SRCCOPY; hBmp = LoadBitmap(hInst, "MYBMP1"); if(hBmp == NULL){ MessageBox(hWnd, "画像1のロードに失敗しました", "エラー", MB_OK | MB_ICONWARNING); return 0; } hdc_mem1 = CreateCompatibleDC(hdc); SelectObject(hdc_mem1, hBmp); hBmp = LoadBitmap(hInst, "MYBMP2"); if(hBmp == NULL){ MessageBox(hWnd, "画像2のロードに失敗しました", "エラー", MB_OK | MB_ICONWARNING); return 0; } hdc_mem2 = CreateCompatibleDC(hdc); SelectObject(hdc_mem2, hBmp); ReleaseDC(hWnd, hdc); break; case WM_PAINT: BeginPaint(hWnd, &ps); hdc_memx = hdc_mem1, hdc_mem2; if(show_no == 1) hdc_memx = hdc_mem1; //変化なし hdc_memx != hdc_mem2;//変化なし if(show_no == 2) hdc_memx = hdc_mem2; /変化なし  hdc_memx != hdc_mem1;/変化なし BitBlt(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, hdc_mem1, ps.rcPaint.left, ps.rcPaint.top, dwRop); BitBlt(ps.hdc, 400,200, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, hdc_mem2, ps.rcPaint.left, ps.rcPaint.top, dwRop); EndPaint(hWnd, &ps); break; case WM_COMMAND: switch (LOWORD(wp)){ case IDM_PICT1: show_no = 1; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_PICT2: show_no = 2; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_SRCCOPY: dwRop = SRCCOPY; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_NOTSRCCOPY: dwRop = NOTSRCCOPY; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_SRCAND: dwRop = SRCAND; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_SRCPAINT: dwRop = SRCPAINT; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0); break; } break; case WM_DESTROY: DeleteObject(hBmp); DeleteObject(hBmp); DeleteDC(hdc_mem1); DeleteDC(hdc_mem2); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } 3、if文のところを色々と変えたのですが、うまく切り替わってくれません。   if(show_no == 1) hdc_memx = hdc_mem1; hdc_memx != hdc_mem2; if(show_no == 2) hdc_memx = hdc_mem2;  hdc_memx != hdc_mem1;

  • windowプログラム ARC C++

    今、windowプログラムで フォームの中に「エディットボックス」と「スタティックテキスト」の2つがあります。 内、スタティックテキスト内にARCで円を描き、表示したいのですがどのようにすればよいのでしょうか? 以上のことに悩んでおります。 某サイトで LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) { HDC hdc; PAINTSTRUCT ps; switch (msg) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_PAINT: hdc = BeginPaint(hwnd , &ps); Arc(hdc , 10 , 10 , 200 , 200 , 0 , 100 , 0, 100); EndPaint(hwnd , &ps); return 0; } return DefWindowProc(hwnd , msg , wp , lp); } int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR lpCmdLine , int nCmdShow ) { HWND hwnd; MSG msg; WNDCLASS winc; winc.style = CS_HREDRAW | CS_VREDRAW; winc.lpfnWndProc = WndProc; winc.cbClsExtra = winc.cbWndExtra = 0; winc.hInstance = hInstance; winc.hIcon = LoadIcon(NULL , IDI_APPLICATION); winc.hCursor = LoadCursor(NULL , IDC_ARROW); winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); winc.lpszMenuName = NULL; winc.lpszClassName = TEXT("-"); if (!RegisterClass(&winc)) return -1; hwnd = CreateWindow(      TEXT("-") , TEXT("-") , WS_OVERLAPPEDWINDOW | WS_VISIBLE , CW_USEDEFAULT , CW_USEDEFAULT , CW_USEDEFAULT , CW_USEDEFAULT ,      NULL , NULL , hInstance , NULL); if (hwnd == NULL) return -1; while(GetMessage(&msg , NULL , 0 , 0)) DispatchMessage(&msg); return msg.wParam; } をコピペしたのですが、スタティックテキスト内表示がわからなく梃子摺っております。 ご存知の方は回答・アドバイスのほどよろしくお願いいたします。

  • ウィンドウが閉じない

    お世話になります。 Adobe Illustratorは起動時にポップアップウィンドウを表示してプラグインを読み込む処理をリアルタイムに見せていますが、それに似た処理をしたいと思っています。 WinMain関数でポップアップウィンドウを生成した後メインウィンドウを生成し、メインウィンドウのWM_CREATEの最後でポップアップウィンドウを消すため ShowWindow(hhwnd, SW_HIDE); や DestroyWindow(hhwnd); を入れました。 ですが、ポップアップウィンドウが消えてくれません。 ポップアップウィンドウは winc.style = CS_HREDRAW | CS_VREDRAW; winc.lpfnWndProc = sWndProc; winc.cbClsExtra = winc.cbWndExtra = 0; winc.hInstance = hInst; winc.hIcon = NULL; winc.hCursor = LoadCursor(NULL, IDC_ARROW); winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); winc.lpszMenuName = NULL; winc.lpszClassName = TEXT("START"); HWND hhwnd = CreateWindowEx(  WS_EX_TOOLWINDOW,  "START", "",  WS_POPUP | WS_VISIBLE | WS_BORDER ,  0 , 0 , 1 , 1 , NULL , NULL ,  hInst , NULL ); で生成し、ウィンドウプロシージャ内は HDC hdc; PAINTSTRUCT ps; static RECT re; int w = 600; int h = 30; switch (msg) { case WM_CREATE:  MoveWindow(hWnd,   (GetSystemMetrics(SM_CXSCREEN)-w)/2,   (GetSystemMetrics(SM_CYSCREEN)-h)/2,   w, h, 1);  InvalidateRect(hWnd, NULL, 1);  break; case WM_PAINT:  hdc = BeginPaint(hWnd, &ps);  SetTextColor(hdc, RGB(0, 0, 0));  if (DrawText(hdc, str, -1, &re, DT_SINGLELINE | DT_CENTER | DT_VCENTER) == 0)   MessageBox(NULL, "err", "", NULL);  EndPaint(hWnd, &ps);  return 0; case WM_SIZE:  GetClientRect(hWnd, &re);  break; } return DefWindowProc(hWnd, msg, wp, lp); のようになっています。ポップアップウィンドウが消えないのはなぜでしょうか。。。

専門家に質問してみよう