2

まず第一に、これは MFC ではありません。これは、私が取り組んできた GUI のトリミングされたバージョンです。

ここに画像の説明を入力

タブ コントロール (デフォルト ウィンドウのハンドルを使用) の上にビットマップ イメージがあることがわかるように、これを「ブルー ビットマップ」と呼びます。問題はなく、完全に機能しています。私が抱えている問題は、別のビットマップ (ディスク上のビットマップ ファイルから) を子ウィンドウ (より具体的にはタブ コントロールの子ウィンドウ) の背景に設定し、灰色を置き換えることです。子ウィンドウ (タブ) の背景としてビットマップを設定しようとしたいくつかのことを次に示します。

1) 最初に LoadImage を使用してビットマップを次のようにインポートすることにより、青色のビットマップをウィンドウに割り当てるために使用したのと同じ方法を使用しました。

index->hbmBitmapBanner = (HBITMAP)LoadImage(index->hInstance,L"Images\\horizontal.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

次に、WM_PAINT メッセージで:

    case WM_PAINT:
    {
        PAINTSTRUCT ps1;
        if (BeginPaint(WINDOWHANDLE,&ps1))
        {
            HDC hdcBanner = CreateCompatibleDC(ps1.hdc);
            HBITMAP hbmOldHorizontal = (HBITMAP)SelectObject(hdcBanner,index->hbmBitmapBanner); // banner
            BitBlt(ps1.hdc,0,0,516,101,hdcBanner,5,0,SRCCOPY);
            SelectObject(hdcBanner,hbmOldHorizontal);
            DeleteDC(hdcBanner);
            EndPaint(WINDOWHANDLE,&ps1);
        }
        break;
    }

そのコードは、青色のビットマップをウィンドウに設定することに成功しましたが、他のビットマップをウィンドウに設定することには成功しませんでした (もちろん、青色のビットマップの変数を代入すると、サイズと方向も変更されます)。画面にビットマップが表示されず、ウィンドウは変更されませんでしたが、機能が失敗することはありませんでした。また、ファイルの場所を交換すると、ビットマップが青いビットマップがあった場所にロードされたので、ロード機能に間違いはありません。

2) 上記のコードを使用して、BeginPaint の最初の引数をタブ コントロール ボックスのウィンドウ ハンドルに変更しようとしましたが、これも役に立たず、ウィンドウは変更されませんでした。また、BeginPaint の最初の引数を情報タブに表示される子ウィンドウに変更しようとしましたが、これにより子ウィンドウ (グループボックス) が消えましたが、まだウィンドウにビットマップは表示されませんでした。

3) 最後の手段として、私は愚かにも子ウィンドウでこの関数を使用しようとしました

SetClassLongPtr(tab->hTabIndex[0],GCLP_HBRBACKGROUND,(DWORD)GetStockObject(BLACK_BRUSH));

そしてもちろん、それはうまくいきませんでした


役に立つ場合は、ウィンドウにタブを作成する方法を次に示します。

TCITEM tie = {0};     
tab->hTab = CreateWindowEx(0,WC_TABCONTROL,L"",WS_CHILD | WS_VISIBLE,0,101,600,400,                    
        WINDOWHANDLE,NULL,(HINSTANCE)GetWindowLong(WINDOWHANDLE,GWLP_HINSTANCE),NULL   
    );

メインのタブ コントロールで、その後に個々のタブ (つまり、情報タブ) が挿入されます。

    TCHAR pszTab1 [] = L"Information";  // tab1's text 
tie.pszText = pszTab1;  // the tab's text/caption
TabCtrl_InsertItem(tab->hTab, 0, &tie); // insert the tab

追加情報: タブ コントロールとウィンドウは、これとは別に完全に動作/相互作用しています。これを1つのタブでのみテスト/試行していました.1つのタブで機能するかどうかはわかっていたので、すべてのタブで機能するため、時間を節約できます.

Charles Petzold 著の Programming For Windows Fifth Edition を参照用に持っています。ビットマップに関するかなり大きなセクションがありますが、彼はビットマップを子ウィンドウにロードすることについては触れていません。メニューのビットマップ。ウィンドウとはまったく異なります。

4

1 に答える 1

3

ここでの問題は、Windows コモン コントロールがメイン スレッドのウィンドウ プロシージャを介してではなく、独自の (システム定義の) ウィンドウ プロシージャを介してアプリケーションと対話することだと思います。

したがって、たとえば、タブ ウィンドウがそれ自体を再描画する場合、コードで定義されたウィンドウ プロシージャに到達する WM_PAINT メッセージに応答して再描画することはありません。WM_PAINT などのウィンドウ プロシージャに渡されたメッセージのウィンドウ ハンドルを調べれば、これが正しいことを自分で確認できるはずです。

共通コントロールのデフォルトの動作を「活用」したい場合は、それを「サブクラス化」する必要があります (こちらを参照)。

タブ コントロールの場合、最善の方法は、タブ コントロールのクライアント領域に合わせたサイズの子ウィンドウの配列を作成し、一度に表示されるウィンドウが選択されたタブに対応するように配置することです。

C++ を使用している場合は、背景 (ビットマップ) 描画が処理されるこれらのウィンドウをラップする基本クラスを作成することを検討してください。次に、個々のタブを処理する一連のラッパーを派生させることができます。私は過去にまさにこのアプローチを使用しており、うまく機能しています。

タブ コントロールのタブは、コントロールのクライアント領域全体に広がるのではなく、文字通りタブそのものであることに注意してください。詳細は覚えていませんが、それらはコントロールによって内部的に処理され、コントロールがサブクラス化されている場合でも、それらを何らかの方法で操作するのはかなり難しいと思います-それについては間違っている可能性があります.

それが役立つことを願っています。

乾杯、イアン。

于 2013-01-12T11:42:32.083 に答える