Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将位图设置为子窗口的背景(WIN32)_C++_Winapi_User Interface_Bitmap_Win32gui - Fatal编程技术网

C++ 如何将位图设置为子窗口的背景(WIN32)

C++ 如何将位图设置为子窗口的背景(WIN32),c++,winapi,user-interface,bitmap,win32gui,C++,Winapi,User Interface,Bitmap,Win32gui,首先,这不是MFC。 以下是我一直在使用的GUI的裁剪版本: 正如您所看到的,选项卡控件上方有一个位图图像(使用默认窗口的句柄),我将其称为“蓝色位图”。我对它没有任何问题,它运行正常。 我遇到的问题是将另一个位图(来自磁盘上的位图文件)设置为子窗口(更具体地说是选项卡控件子窗口)的背景,以替换灰色。下面是我为尝试并将位图设置为子窗口(选项卡)的背景所做的一些事情 1) 我使用与将蓝色位图分配给窗口相同的方法,首先使用LoadImage导入位图,如下所示: index->hbmBitmap

首先,这不是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的第一个参数更改为显示在“信息”选项卡上的子窗口,这导致子窗口(一个groupbox)消失,但窗口上仍然没有显示位图

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   
    );
是主选项卡控件,然后插入各个选项卡(即信息选项卡)

其他信息:除此之外,选项卡控件和窗口的工作/交互都非常完美。我只对一个选项卡进行了测试/尝试,因为我知道如果它在一个选项卡上工作,那么它将在所有选项卡上工作,从而节省时间


我旁边有Charles Petzold的《Windows第五版编程》作为参考,关于位图有一个相当大的部分,但他没有谈到将位图加载到子窗口,他得到的最接近的结果是使用菜单中的位图,这与窗口完全不同。

我认为这里的问题是,Windows通用控件不通过主线程的窗口过程与应用程序交互,而是通过它们自己的(系统定义的)窗口过程

因此,例如,当选项卡窗口重新绘制自身时,它不会响应到达代码中定义的窗口过程的WM_PAINT消息。通过检查传递给窗口过程的消息的窗口句柄(例如WM_PAINT),您应该能够自己验证这一点

如果您希望“利用”公共控件的默认行为,您必须“子类化”它(请参阅),但根据我的经验,尝试更改重新绘制行为通常是有问题的

对于选项卡控件,最好的做法是创建一个大小与选项卡控件的客户端区域相对应的子窗口数组,并安排在任何时候显示的子窗口与所选选项卡相对应

如果你使用C++,你可以考虑创建一个基类来封装这些背景(位图)的处理。然后可以派生一系列包装器来处理每个单独的选项卡。我在过去使用过这种方法,效果很好

请记住,选项卡控件的选项卡并不扩展到控件的整个客户端区域,而是选项卡本身。我不记得细节了,但我认为它们是由控件内部处理的,以任何方式操纵它们都是相当棘手的,即使控件是子类化的,这可能是错误的

希望有帮助


干杯,伊恩。

告诉我们更多关于选项卡的子窗口(处理
WM_PAINT
代码片段的窗口)。它是如何创建的?它的窗口程序看起来怎么样?也许您在消息切换之后调用DefWindowProc(),它可能会立即再次重新绘制,从而从屏幕上删除位图?
    TCHAR pszTab1 [] = L"Information";  // tab1's text 
tie.pszText = pszTab1;  // the tab's text/caption
TabCtrl_InsertItem(tab->hTab, 0, &tie); // insert the tab