我在使用函数SHAutoComplete
时遇到问题。当我在父窗口不是对话框的编辑框中使用它时,它无法正常工作。
自动完成功能似乎工作正常,但下拉列表的渲染与可能的候选基于编辑框中输入的内容非常混乱。基本上只显示下拉菜单的边框。边框的宽度足以满足可能的建议,但建议本身从未被绘制。即使是下拉列表背景颜色也是错误的。就好像它从未被绘制过并保持原始父窗口颜色。
如果建议的数量足够大,因此下拉列表需要滚动条,滚动条也无法正确呈现 - 箭头不会被绘制。
在这两种情况下,无论是否有滚动条,下拉列表都不接受鼠标输入,即我无法点击这些项目。如果我在显示下拉菜单时按下键盘上的“向下”键,它会按预期工作。在第二次或第三次按下后,项目最终开始出现。但滚动条仍然无法正确呈现。
如果不是注册我自己的Windows类,而只是使用::DialogBoxParam()
的对话框,那么一切都按预期进行。自动完成工作完全没有任何问题。
这是我正在做的事情。此代码将注册一个窗口类,创建主窗口,创建一个编辑框,然后在其上调用SHAutoComplete
。它必须与Shlwapi.lib
// this code must be linked with Shlwapi.lib
#include <Windows.h>
#include <Shlwapi.h>
// name of the class that will be created for the main window
static const char WindowClassName[] = "SHAutoCompleteDoesNotWorkWithoutADialogWindowClassName";
// the main window procedure
static LRESULT CALLBACK WindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
{
HWND hwndEdit = ::CreateWindowEx(
0,
"EDIT",
0,
WS_CHILD | WS_VISIBLE,
10,
10,
300,
25,
hwnd,
NULL,
NULL,
0);
::SHAutoComplete(hwndEdit, SHACF_DEFAULT);
return 0;
}
case WM_DESTROY:
::PostQuitMessage(1);
return 0;
default:
return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
// the app entry point
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
::CoInitialize(NULL);
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof(wcex);
wcex.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW ;
wcex.lpfnWndProc = WindowProc;
wcex.hInstance = hInstance;
wcex.lpszClassName = WindowClassName;
wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
ATOM atom = ::RegisterClassEx(&wcex);
HWND hwnd = ::CreateWindowEx(
0,
MAKEINTATOM(atom),
"SHAutoComplete Test",
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
MSG msg;
while(::GetMessage(&msg, hwnd, 0, 0) > 0)
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
::UnregisterClass((LPCTSTR)atom, NULL);
::CoUninitialize();
return 0;
}
该代码产生以下内容:
需要滚动条时的下拉列表 http://www.abload.de/img/shautocomplete_2i1sk4.jpg
几次按下“向下”键后的下拉菜单。请注意滚动条仍然无法正确呈现。 http://www.abload.de/img/shautocomplete_3efsgw.jpg
现在,当我切换到对话框时,就像魅力一样。在下面的代码中,IDD_DIALOG1只是一个空的对话框资源,由IDE自动创建。
以下是rc文件的相关部分
IDD_DIALOG1 DIALOGEX 0, 0, 316, 185
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
END
以下是使用它的代码
// this code must be linked with Shlwapi.lib
#include <windows.h>
#include <Shlwapi.h>
#include "Resource.h"
BOOL CALLBACK DialogProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
HWND hwndEdit = ::CreateWindowEx(
0,
"EDIT",
0,
WS_VISIBLE | WS_CHILD,
0,
0,
300,
20,
hwnd,
NULL,
NULL,
0);
::SHAutoComplete(hwndEdit, SHACF_DEFAULT);
return 1;
}
case WM_CLOSE:
::EndDialog(hwnd, 0);
return 1;
default:
return 0;
}
}
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
::CoInitialize(NULL);
::DialogBoxParam(
NULL,
MAKEINTRESOURCE(IDD_DIALOG1),
NULL,
DialogProc,
0);
::CoUninitialize();
return 0;
}
你能指出我哪里出错吗?据我所知,除了主窗口的创建和破坏之外,两者之间似乎没有任何区别。我在SHAutoComplete文档中遗漏了哪些内容,表明它只能在对话框中的编辑框中使用?
答案 0 :(得分:5)
您正在使用过滤的消息循环,因此不会处理下拉列表的任何消息。将NULL作为第二个参数传递给GetMessage