没有对话框的编辑控件上的SHAutoComplete

use*_*842 3 c c++ winapi

我在使用该功能时遇到问题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;
}       
Run Code Online (Sandbox Code Playgroud)

该代码产生以下内容:

  1. 需要滚动条时的下拉菜单 http://www.abload.de/img/shautocomplete_2i1sk4.jpg

  2. 几次按下"向下"键后的下拉菜单.请注意滚动条仍然无法正确呈现. 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
Run Code Online (Sandbox Code Playgroud)

以下是使用它的代码

// 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;
}
Run Code Online (Sandbox Code Playgroud)

你能指出我哪里出错吗?据我所知,除了主窗口的创建和破坏之外,两者之间似乎没有任何区别.我在SHAutoComplete文档中遗漏了一些内容,表明它只能在对话框中的编辑框中使用吗?

Ray*_*hen 5

您正在使用筛选的消息循环,因此不会处理下拉列表的任何消息.将NULL作为GetMessage的第二个参数传递