none
ダイアログのタイトルバーの描画について教えてください。 RRS feed

  • 質問

  • CreateDialog(CreateWindowではない)を用いて作成されたDialogのタイトルバーに描画したいのですが
    コールバック関数中のメッセージWM_NCPAINTで描画することはできないのでしょうか?

    LRESULT CALLBACK WindowProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    switch (msg) {
    case WM_NCPAINT: {
    LRESULT lr;
    lr = DefWindowProc(wnd, msg, wParam, lParam);
    //ここで描画
    return lr;
    }

    2021年4月14日 21:57

回答

  • 亀レスですみません。
    ダイアログ含めて、あるウィンドウのノンクライアント(NC)領域に何か書き込むには

    (1) ::GetWindowDC( HWND);を使って、NC専用のHDCを取得します。


    後は通常の描画と同じです。
    WindowsSDK(=Win32SDK)で書いみると以下のようになります。

    HDC     hdc	= GetWindowDC( m_hWnd);
    HPEN   Pen	= CreatePen( PS_SOLID, 3, RGB( 255, 0, 0));
    HPEN   PenOld	= ( HPEN)SelectObject( hdc, Pen);
    
    MoveToEx( hdc, 4, 4, NULL);	// 赤い線を引いてみる
    LineTo( hdc, 500, 4);
    
    SelectObject( hdc, PenOld);
    DeleteObject( Pen);
    ReleaseDC( m_hWnd, hdc);


    座標がいい加減なのでよろしく・・・。
    ちなみに、GetDCEx()を使ったサンプルは動かないですよね(忘れましょう)。

    2021年4月16日 1:49

すべての返信

  • 亀レスですみません。
    ダイアログ含めて、あるウィンドウのノンクライアント(NC)領域に何か書き込むには

    (1) ::GetWindowDC( HWND);を使って、NC専用のHDCを取得します。


    後は通常の描画と同じです。
    WindowsSDK(=Win32SDK)で書いみると以下のようになります。

    HDC     hdc	= GetWindowDC( m_hWnd);
    HPEN   Pen	= CreatePen( PS_SOLID, 3, RGB( 255, 0, 0));
    HPEN   PenOld	= ( HPEN)SelectObject( hdc, Pen);
    
    MoveToEx( hdc, 4, 4, NULL);	// 赤い線を引いてみる
    LineTo( hdc, 500, 4);
    
    SelectObject( hdc, PenOld);
    DeleteObject( Pen);
    ReleaseDC( m_hWnd, hdc);


    座標がいい加減なのでよろしく・・・。
    ちなみに、GetDCEx()を使ったサンプルは動かないですよね(忘れましょう)。

    2021年4月16日 1:49
  • 仲澤@失業者 様、ご回答ありがとうございます。

    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    HDC hdc;
    HPEN Pen;
    HPEN PenOld;
    switch (msg) {
    case WM_NCPAINT:
    hdc = GetWindowDC(hwnd);
    Pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
    PenOld = (HPEN)SelectObject(hdc, Pen);
    MoveToEx(hdc, 4, 4, NULL); // 赤い線を引いてみる
    LineTo(hdc, 500, 4);
    SelectObject(hdc, PenOld);
    DeleteObject(Pen);
    ReleaseDC(hwnd, hdc);
    break;
    ...

    CreateWindowで作成し、上記のコードを実行してみたのですが
    Windows10 赤い線がない
    windowsXP 赤い線がある
    という結果になりました。

    http://hsp.tv/play/pforum.php?mode=pastwch&num=86451
    "Windows 8.1 及び Windows 10 でのタイトルバー(キャプション)のカラーは、
    DWM (Desktop Window Manager) が担当しています。
    タイトルバーのカラーは DWM 側で合成処理を行っているので、色の設定をするにはレジストリを直接変更し、
    変更後アクティブだったウィンドウのウィンドウ全体を更新してください。"

    とあるので、Windows 10の場合、WM_NCPAINTではタイトルバーの変更はできないのではと考え
    試しにWindows10で次のコードを実行したところ
     if (DwmSetWindowAttribute(Handle, 19, new[] { 1 }, 4) != 0)
        DwmSetWindowAttribute(Handle, 20, new[] { 1 }, 4);
     
    タイトルバーが黒くなりました。
    (上記のHPにあるレジストリ、コンピューター\HKEY_CURRENT_USER\Software\Microsoft\Windows\DWMの
    ColorPrevalenceが1だと黒くなりません)
    2021年4月16日 21:14
  • なるほどですね。
    Windows10でも一時的になら赤線を描画できます。
    ただし、WM_NCPAINTを一瞬でもデフォルトプロシージャに渡すとDWMになってしまう様なので、
    デフォルトプロシージャに渡さずに、握りつぶす必要がありそうです。
    また、再描画の時にも工夫が必要な様で、自然な感じに維持するのは結構難しそうですね。


    2021年4月19日 2:21