PathToRegion()について

このQ&Aのポイント
  • hRgn = PathToRegion(hdc)で生成されるhRgnのオブジェクトは生成されるのか?
  • hRgn = PathToRegion(hdc)の結果はリージョンの演算結果が変わるだけか?
  • このソースコードはメモリリークを引き起こしているか?PathToRegionの動作は?
回答を見る
  • ベストアンサー

PathToRegion()について

case WM_TIMER: hdc = GetDC(hwnd); SelectObject(hdc, font); SetBkMode(hdc, TRANSPARENT); BeginPath(hdc); TextOut(hdc, 0, 0, mt->ShowNowTime(mt), lstrlen(mt->ShowNowTime(mt))); EndPath(hdc); hRgn = PathToRegion(hdc); ←ここです。 SelectObject(hdc , GetStockObject(SYSTEM_FONT)); ReleaseDC(hwnd, hdc); SetWindowRgn(hwnd, hRgn, TRUE); InvalidateRect(hwnd, NULL, FALSE); return 0; 時計(文字のみ)のデスクトップアクセサリーをつくろうと思ってますが、 hRgn = hRgn = PathToRegion(hdc);で繰り返し同じhRgnで生成したら、 hRgnのオブジェクト自体はまた生成されるのでしょうか?それともリージョンの演算結果が変わるだけでしょうか? このソースはメモリリークをおこしているでしょうか? PathToRegionはどのような動作をしているのでしょうか? 分かる方教えてください。 (いい文章の表現方法がわからなかったため直接疑問点を書いてみました。文章へたですみません。)

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

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

  • ベストアンサー
回答No.2

勿論PathToRegionを呼び出すたびに新たにリージョンが生成されます。その場合、以前のリージョンを破棄する必要があるかどうかですね。 一般的にはregionはGDIオブジェクトですので、使用した後はDeleteObjectで破棄する必要があります(*1)。ただし、SetWindowRgnでウィンドウに関連付けた場合、SDKによると"(Y)ou should not make any further function calls with this region handle. In particular, do not close this region handle."とあるので、ウィンドウを破棄した場合やSetWindowRgnで別なリージョンを設定したときに勝手にシステムの側で破棄してくれるようですね。 それともうひとつ。上のコードでは時刻が変わっても即座に再描画されません。そこでInvalidateRectの後でUpdateWindowかRedrawWindowを呼び出して強制的に再描画したほうがよいでしょう。 *1.上のコードで使っているfontも同じくGDIオブジェクトですので、どこかで破棄する必要があります。

sizum
質問者

お礼

ほんとうにありがとうございます。いろいろネットでリージョンに関して探してもこの関数だけは全然情報が少なく、もしあっても基本的な使い方しかのってなく困ってました。心の靄が晴れた気分です^^(やっぱり英語は読めるようにならないと・・・)

その他の回答 (1)

回答No.1

hRgn = hRgn = PathToRegion(hdc); このコードは全く問題なく実行されるはずですが。つまり上のコードは hRgn = PathToRegion(hdc); hRgn = hRgn; と同じことです。hRgnにそのまま自身の値をコピーしているだけで、同じパスからリージョンを二回以上生成しているわけではありません。 もしリージョンを二回以上生成したらどうなるかというご質問なら、Win32SDKのヘルプに "After PathToRegion converts a path into a region, Windows discards the closed path from the specified device context. " とありますので、二回目の関数コールでエラーになると予想できます。実際に二回呼び出してみれば確認できると思います。

sizum
質問者

補足

すみません^^; hRgn = hRgn = PathToRegion(hdc)は記入ミスです。 コピペしたときの消し忘れです。すいませんでした。 質問内容は タイマー関数で一定時間毎に (hRgnは静的) hRgn = PathToRegion(hdc);を呼び出した場合、毎回オブジェクト自体を生成しているのか、 それとも演算結果が変更されるのかどうかということを知りたかったという 質問です。すみませんでした。

関連するQ&A

  • グラフィカルパスについて

    グラフィカルパスについて教えてほしいことが2つあるんですが。 (1)1つ目は下記のソースのようにでフォントを作成しないと描画できないないのですが、その理由を教えて下さい。 デフォルトのフォントだとなぜダメなのでしょうか? (2)2つ目はフォントを作成した場合に、SetBkMode()の部分をコメントアウトすると、背景が塗りつぶされ、文字が塗りつぶされませんが、どうしてでしょうか?(このときフォント作成のコメントアウトは解除して下さい) MSDNにFillPath()の説明に「パスの内部を塗りつぶす」とありますが、このとき文字は「内部」の扱いにならないのでしょうか? どれが内部でどれが外部になるのかよく理解できていないだと思います。 // HFONT hFont; char Str[] = "ABCDE"; HDC hdc = GetDC( hWnd ); BeginPath( hdc ); SetBkMode( hdc, TRANSPARENT ); /* hFont = CreateFont( 80, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET ,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS ,DEFAULT_QUALITY, 0 ,NULL ); SelectObject( hdc ,hFont ); */ TextOut( hdc, 0, 0, Str, lstrlen(Str) ); EndPath( hdc ); SelectObject( hdc, CreateHatchBrush(HS_DIAGCROSS ,0xFF) ); FillPath( hdc ); SelectObject( hdc ,GetStockObject( SYSTEM_FONT ) ); // DeleteObject( hFont ); DeleteObject( SelectObject( hdc, GetStockObject(WHITE_BRUSH) ) ); ReleaseDC( hWnd, hdc ); どなたか分かる方いらっしゃいましたらご教授下さい。 よろしくお願いします。

  • TextOut( ) を BeginPaint( ) と GetDC( )

    LRESULT CALLBACK の case WM_PAINT: で、 hdc = BeginPaint(hWnd, &ps); TextOut(hdc,0,0,str,strlen(str)); EndPaint(hWnd, &ps); ↑問題無し。↓文字がちらつく。 hdc = GetDC(hWnd); TextOut(hdc,0,0,str,strlen(str)); ReleaseDC(hWnd,hdc); ちらつきの原因は、高速で TextOut( ) が繰り返されるから だと思いました。 どうして TextOut( ) が繰り返されるんですか? 上の方法の場合は、 ReleaseDC(hWnd,hdc); は書かなくてもいいですか?

  • 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()もつかっていないのですが。 いつシステムから送られるかご教授をお願いします。

  • SetBkMode( ) (HBRUSH)GetStockObject( )

     case WM_PAINT:   hDC = BeginPaint(hWnd, &ps);   SetBkMode(hDC, LTGRAY_BRUSH);   TextOut(hDC,0,0,szHello,strlen(szHello));   EndPaint(hWnd, &ps);  break; これは、int WINAPI WinMain( ) で wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); としてないと、SetBkMode( ) が無効になりました。 GetStockObject( ) の意味を知らないけど、これによって LTGRAY という色が特別なものになるんだと思いました。 窓の背景色を wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); で黒にした場合に、TextOut( ) の背景色を灰色にするには どう書けばいいんですか?

  • リサイズで文字が消えちゃう

    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {  HDC hdc;  char *str;  switch (msg) {   case WM_KEYDOWN:   hdc = GetDC(hWnd);   str = "キーダウンした";   TextOut(hdc,1,1,str,strlen(str));   ReleaseDC(hWnd,hdc);   break; キーを押すと、LRESULT CALLBACK でウインドウに文字が 表示されるようにしました。 でも、この文字は別のウインドウに隠れて、再びウインドウが 表示された場合とかには消えています。 消えないようにするためにはどうしたらいいですか? void Swit(HWND hWnd) {  HDC hdc;  char *str;  if (キーダウンのフラグがあったとして、それが true なら) {   hdc = GetDC(hWnd);   str = "キーダウンした";   TextOut(hdc,1,1,str,strlen(str));   ReleaseDC(hWnd,hdc);  } return; } if ( ウインドウ再描画 == true ){ Swit() } というのを考えました。 LRESULT CALLBACK で、キーが押された場合にフラグを true にして ウインドウが再描画された場合にフラグをチェックして文字を 表示する という方法を考えたんだけど、これを BCC32 でコンパイル するためにはどういうソースを書いたらいいか分からないし、 もっといい方法があれば教えてください。

  • (SHORT)

    ウインドウプロシージャ内ですが、(SHORT)は何のためについているんでしょうか?(どんな効果がありますか) 教えてください。 case WM_MOUSEWHEEL :     wsprintf(str,TEXT("WHEEL %s"),        ((SHORT)HIWORD(wparam))>0 ? TEXT("↑"):TEXT("↓"));     hdc=GetDC(hwnd);     TextOut(hdc,0,0,str,lstrlen(str));

  • VOID型をSTRUCTのように

    LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){  HDC hDC;  PAINTSTRUCT ps;  static void *v = "abcdefg";  switch(msg){  case WM_PAINT:   hDC = GetDC(hWnd);   TextOut(hDC, 0, 0, (char*)v, strlen((char *)v));   ReleaseDC(hWnd, hDC);   ValidateRect(hWnd, NULL);  break; これで abcdefg が表示されるけど、defg を表示される方法が 分かりません。 abcdefg の文字列の長さは不明です。 char buf[1000]; のように大きく確保すればいいんだけど、そういうのをせず、 動的にやろうと考えています。   TextOut(hDC, 0, 0, &(((char*)v)+3), strlen((char *)v)-3); だと、メモリ上に配置されなければならない というエラーになります。 よい方法があったら教えてください。

  • BeginPaintの使い方

    現在windowsプログラミングを勉強しています。 まだまだはじめたばかりでwindowsプログラミングの把握できていない部分が多々あるので、何か使い方が根本的に間違えているところがあるかもしれませんが、ご容赦ください。 case WM_PAINT: hdc=BeginPaint(hdc,&ps);/*rc,hdc等は宣言済み*/ TextOut(hdc,0,0,szStr,(int)strlen(szStr));/*szStr="文字列"代入済み*/ EndPaint(hWnd,&ps);/*hWnd等は宣言済み*/ break; において、 1.ダブルクリックしたら表示させよう!と思いまして、 WM_PAINT→WM_RBUTTONDBLCLKSと変更したところ表示されなくなりました。 しかし、hdc取得をGetDCで行うとうまくいきました。この違いがよくわかりません。 2.次はダブルクリックすると文字を右に動かそう!と思いまして、 TextOut(hdc,i,0,・・・・)などといたしましてiを増やしたところ更新前の画像が残りました。そこでInvalidateRectによって背景消去しようとおもいまして、TextOutの前に挿入しましたがこれによっても初めから、クリック後も何も表示されなくなりました。 1と2の2点に関して、どなたかご教授いただけないでしょうか。よろしくお願いします。

  • なぜhButton1ボタンからのWM_COMMANDはフックできてクライアントエリアのWM_RBUTTONDOWNはフックできないのでしょうか?

    #define STRLBUTTON TEXT("マウス左ボタンが押されました from mainProc") #define STRRBUTTON TEXT("マウス右ボタンが押されました from my_HookProc") #define STRCOMMAND TEXT("ボタンが押されました") HWND hButton1; LRESULT CALLBACK my_HookProc(int nCode, WPARAM wParam, LPARAM lParam) { CWPRETSTRUCT *pcwpRetStruct = (CWPRETSTRUCT *)lParam; HDC hDC; if(nCode==HC_ACTION) { hDC = GetDC(pcwpRetStruct->hwnd); switch(pcwpRetStruct->message) { case WM_COMMAND: TextOut(hDC, 10, 10, STRCOMMAND, strlen(STRCOMMAND)); break; case WM_RBUTTONDOWN: TextOut(hDC, 10, 10, STRRBUTTON, strlen(STRRBUTTON)); break; } ReleaseDC(pcwpRetStruct->hwnd, hDC); } return CallNextHookEx(NULL, nCode, wParam, lParam); } LRESULT CALLBACK mainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HHOOK hHook; HDC hDC; switch(uMsg) { case WM_DESTROY: UnhookWindowsHookEx(hHook); PostQuitMessage(0); return 0; case WM_CREATE: hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, my_HookProc, NULL, GetCurrentThreadId() ); if(!hHook) MessageBox(NULL, "hooking failed", NULL, MB_OK); hButton1 = CreateWindow( "BUTTON", "hButton1", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 40, 100, 20, hWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL ); return 0; case WM_LBUTTONDOWN: hDC = GetDC(hWnd); TextOut(hDC, 10, 10, STRLBUTTON, strlen(STRLBUTTON)); ReleaseDC(hWnd, hDC); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }

  • wParam

    wParamは、unsigned int型で、仮想キーコードを、格納してますよね。 wsprintf()内で(TCHAR)キャストしてますが、 これは、変数strの型がTCHAR型なので(wParamは、unsigned intなので型をあわせるために)やっているんですか? (TCHAR)キャストしないとエラーになりますか?教えてください。 HDC hdc; TCHAR str[255]; swich(umsg){   case WM_CHAR:     wsprintf( str, TEXT("%c"), (TCHAR)wPara );     hdc = GetDC(hwnd);     TextOut(hdc, 0, 0, str, lstrlen(str));     return0 }