我在 Windows 10 上使用 MinGW32 和 Code::Blocks IDE。我尝试通过“BUTTON_IMAGELIST”将图像列表分配给按钮,但“SendMessage”函数总是失败(返回“0”)。但是,“GetLastError()”也没有给我错误。将单个图像分配给按钮是可行的,但对于图像列表,按钮将保持空白。我在这里做错了什么?
主.cpp
#include <iostream>
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
HIMAGELIST ImageList;
LRESULT CALLBACK WindowProcedure ( HWND WindowHandle, UINT message, WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_CREATE:
{
HWND ButtonOne = CreateWindowEx( 0, "BUTTON", "", BS_PUSHBUTTON | BS_BITMAP | WS_CHILD | WS_VISIBLE, 40, 10, 50, 50, WindowHandle, (HMENU)( IDC_BUTTON_ONE ), GetModuleHandle( nullptr ), nullptr );
HANDLE Image = LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDB_BITMAP_SQUARE ), IMAGE_BITMAP, 50, 50, LR_DEFAULTCOLOR );
ImageList = ImageList_Create( 50, 50, ILC_COLORDDB, 1, 0 );
ImageList_Add( ImageList, (HBITMAP)Image, nullptr );
RECT rect = { 0, 0, 50, 50 };
BUTTON_IMAGELIST *ButtonImageList = new BUTTON_IMAGELIST;
ButtonImageList->himl = ImageList;
ButtonImageList->margin = rect;
ButtonImageList->uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;
std::cout << SendMessage( ButtonOne, BCM_SETIMAGELIST, (WPARAM)0, (LPARAM)( ButtonImageList ) ); //output = 0
}
break;
case WM_DESTROY:
ImageList_Destroy( ImageList );
PostQuitMessage ( 0 );
break;
default:
return DefWindowProc ( WindowHandle, message, wParam, lParam );
}
return 0;
}
const std::string WindowClassName = "CommonControlsTest";
int WINAPI WinMain ( HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow )
{
INITCOMMONCONTROLSEX *ComCon;
ComCon->dwSize = sizeof( INITCOMMONCONTROLSEX );
ComCon->dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx( ComCon );
HWND WindowHandle;
MSG Messages;
WNDCLASSEX WindowClass;
WindowClass.hInstance = hThisInstance;
WindowClass.lpszClassName = WindowClassName.c_str();
WindowClass.lpfnWndProc = WindowProcedure;
WindowClass.style = CS_DBLCLKS;
WindowClass.cbSize = sizeof ( WNDCLASSEX );
WindowClass.hIcon = LoadIcon ( NULL, IDI_APPLICATION );
WindowClass.hIconSm = LoadIcon ( NULL, IDI_APPLICATION );
WindowClass.hCursor = LoadCursor ( NULL, IDC_ARROW );
WindowClass.lpszMenuName = NULL;
WindowClass.cbClsExtra = 0;
WindowClass.cbWndExtra = 0;
WindowClass.hbrBackground = reinterpret_cast<HBRUSH>( COLOR_BACKGROUND );
if ( !RegisterClassEx ( &WindowClass ) )
return 0;
WindowHandle = CreateWindowEx ( 0, WindowClassName.c_str(), "Common Controls Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, HWND_DESKTOP, NULL, hThisInstance, NULL );
ShowWindow ( WindowHandle, nCmdShow );
UpdateWindow( WindowHandle );
while ( ( GetMessage ( &Messages, NULL, 0, 0 ) ) )
{
TranslateMessage( &Messages );
DispatchMessage( &Messages );
}
return Messages.wParam;
}
资源.rc
#include "Resource.h"
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "CommonControlsTest.exe.manifest"
IDB_BITMAP_SQUARE BITMAP "Square.bmp"
资源.h
#define IDC_BUTTON_ONE 101
#define IDB_BITMAP_SQUARE 201
CommonControlsTest.exe.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="CompanyName.ProductName.YourApplication"
type="win32"
/>
<description>Your application description here.</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
您的
resource.h
文件需要将 CREATEPROCESS_MANIFEST_RESOURCE_ID
和 RT_MANIFEST
常量分别定义为 1 和 24。
资源.h
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST 24
#define IDC_BUTTON_ONE 101
#define IDB_BITMAP_SQUARE 201
此外,您不需要动态分配
BUTTON_IMAGELIST
(您正在泄漏它):
RECT rect = { 0, 0, 50, 50 };
BUTTON_IMAGELIST ButtonImageList;
ButtonImageList.himl = ImageList;
ButtonImageList.margin = rect;
ButtonImageList.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;
std::cout << SendMessage( ButtonOne, BCM_SETIMAGELIST, 0, (LPARAM) &ButtonImageList );