如何在运行时更改组合框下拉样式?
How doI change combobox's drop down style at runtime?
如何在运行时更改组合框的样式下拉样式?我试过使用 SetWindowLongPtr()
但它既没有改变样式也没有 return 任何错误。我正在尝试从单击按钮开始进行如下更改。缺少什么:
这是处理它的一段代码:
assert(SetWindowLongPtr(hwndCombo, GWL_STYLE, WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST));
assert(SetWindowPos(hwndCombo,
0, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW));
完整代码如下:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <assert.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hinst;
int comboStyle = CBS_SIMPLE;
int createButton = 1;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR lpCmdLine, int nCmdShow) {
HWND hwnd;
MSG msg ;
WNDCLASSW wc = {0};
wc.lpszClassName = L"Application";
wc.hInstance = hInstance ;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc ;
wc.hCursor = LoadCursor(0,IDC_ARROW);
g_hinst = hInstance;
RegisterClassW(&wc);
hwnd = CreateWindowW(wc.lpszClassName, L"Combo box",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 270, 170, 0, 0, hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0)) {
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
static HWND hwndCombo;
const wchar_t *items[] = { L"foo", L"baa", L"lol" };
switch(msg)
{
case WM_CREATE:
{
hwndCombo = CreateWindow(L"Combobox", NULL,
WS_CHILD | WS_VISIBLE | comboStyle,
10, 10, 120, 110, hwnd, NULL, g_hinst, NULL);
if(createButton)
{
CreateWindow(L"Button", L"Change Style",
WS_CHILD | WS_VISIBLE,
150, 10, 90, 25, hwnd, (HMENU) 1, g_hinst, NULL);
}
for (int i = 0; i < sizeof(items)/sizeof(items[0]); ++i)
{
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) items[i]);
}
}
break;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED)
{
//MessageBox(NULL, L"!", NULL, MB_OK);
comboStyle = CBS_DROPDOWNLIST;
createButton = 0;
//InvalidateRect(hwndCombo, NULL, TRUE);
//SendMessage(hwnd, WM_CREATE, 0, lParam);
assert(SetWindowLongPtr(hwndCombo, GWL_STYLE, WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST));
assert(SetWindowPos(hwndCombo,
0, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW));
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
尽管 document 说:
If you have changed certain window data using SetWindowLong
, you must
call SetWindowPos
for the changes to take effect. Use the following
combination for uFlags: SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED
.
但有些样式仅在window创建时生效,因此无法通过此调用设置。
如果您想在运行时修改静态控件的样式,最好的选择是简单地销毁并重新创建具有新样式的控件:
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED)
{
comboStyle = CBS_DROPDOWNLIST;
createButton = 0;
DestroyWindow(hwndCombo);
hwndCombo = CreateWindow(L"Combobox", NULL,
WS_CHILD | WS_VISIBLE | comboStyle,
10, 10, 120, 110, hwnd, NULL, g_hinst, NULL);
for (int i = 0; i < sizeof(items) / sizeof(items[0]); ++i)
{
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)items[i]);
}
}
break;
更多参考资料:Change Win32 Window Style, SetWindowLong() function doesn't change window style even after calling SetWindowPos()
如何在运行时更改组合框的样式下拉样式?我试过使用 SetWindowLongPtr()
但它既没有改变样式也没有 return 任何错误。我正在尝试从单击按钮开始进行如下更改。缺少什么:
这是处理它的一段代码:
assert(SetWindowLongPtr(hwndCombo, GWL_STYLE, WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST));
assert(SetWindowPos(hwndCombo,
0, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW));
完整代码如下:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <assert.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hinst;
int comboStyle = CBS_SIMPLE;
int createButton = 1;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR lpCmdLine, int nCmdShow) {
HWND hwnd;
MSG msg ;
WNDCLASSW wc = {0};
wc.lpszClassName = L"Application";
wc.hInstance = hInstance ;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc ;
wc.hCursor = LoadCursor(0,IDC_ARROW);
g_hinst = hInstance;
RegisterClassW(&wc);
hwnd = CreateWindowW(wc.lpszClassName, L"Combo box",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 270, 170, 0, 0, hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0)) {
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
static HWND hwndCombo;
const wchar_t *items[] = { L"foo", L"baa", L"lol" };
switch(msg)
{
case WM_CREATE:
{
hwndCombo = CreateWindow(L"Combobox", NULL,
WS_CHILD | WS_VISIBLE | comboStyle,
10, 10, 120, 110, hwnd, NULL, g_hinst, NULL);
if(createButton)
{
CreateWindow(L"Button", L"Change Style",
WS_CHILD | WS_VISIBLE,
150, 10, 90, 25, hwnd, (HMENU) 1, g_hinst, NULL);
}
for (int i = 0; i < sizeof(items)/sizeof(items[0]); ++i)
{
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) items[i]);
}
}
break;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED)
{
//MessageBox(NULL, L"!", NULL, MB_OK);
comboStyle = CBS_DROPDOWNLIST;
createButton = 0;
//InvalidateRect(hwndCombo, NULL, TRUE);
//SendMessage(hwnd, WM_CREATE, 0, lParam);
assert(SetWindowLongPtr(hwndCombo, GWL_STYLE, WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST));
assert(SetWindowPos(hwndCombo,
0, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW));
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
尽管 document 说:
If you have changed certain window data using
SetWindowLong
, you must callSetWindowPos
for the changes to take effect. Use the following combination for uFlags:SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED
.
但有些样式仅在window创建时生效,因此无法通过此调用设置。
如果您想在运行时修改静态控件的样式,最好的选择是简单地销毁并重新创建具有新样式的控件:
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED)
{
comboStyle = CBS_DROPDOWNLIST;
createButton = 0;
DestroyWindow(hwndCombo);
hwndCombo = CreateWindow(L"Combobox", NULL,
WS_CHILD | WS_VISIBLE | comboStyle,
10, 10, 120, 110, hwnd, NULL, g_hinst, NULL);
for (int i = 0; i < sizeof(items) / sizeof(items[0]); ++i)
{
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)items[i]);
}
}
break;
更多参考资料:Change Win32 Window Style, SetWindowLong() function doesn't change window style even after calling SetWindowPos()