3

機能の使用に問題がありますSHAutoComplete。親ウィンドウがダイアログ ボックスではない編集ボックスで使用すると、正しく動作しません。

オートコンプリート機能は正常に動作しているように見えますが、編集ボックスに入力された内容に基づいて可能な候補を含むドロップダウン リストのレンダリングが非常に混乱しています。基本的に、ドロップダウンの境界のみが表示されます。境界線は可能な候補に合うように十分広くレンダリングされますが、候補自体は決して描画されません。ドロップダウン リストの背景色も間違っています。あたかもペイントされていないかのように、元の親ウィンドウの色のままです。

また、候補の数が多すぎてドロップダウンにスクロール バーが必要な場合、スクロール バーも正しくレンダリングされず、矢印が描画されません。

どちらの場合も、スクロールバーの有無にかかわらず、ドロップダウン リストはマウス入力を受け入れません。つまり、アイテムをクリックできません。ドロップダウンが表示されているときにキーボードの「下」キーを押すと、期待どおりに機能します。2 回目または 3 回目のプレスの後、アイテムが最終的に表示され始めます。しかし、スクロールバーはまだ正しくレンダリングされません。

独自の 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;
}       

そのコードは以下を生成します。

  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

そして、ここにそれを使用するコードがあります

// 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;
}

私が間違っているところを指摘していただけますか?私が見る限り、メイン ウィンドウの作成と破棄以外には、この 2 つの間にまったく違いはないようです。SHAutoComplete ドキュメントに、ダイアログ内の編集ボックスでのみ使用できると記載されているものがありませんか?

4

1 に答える 1

5

フィルタリングされたメッセージ ループを使用しているため、ドロップダウンのメッセージは処理されません。GetMessage の 2 番目のパラメーターとして NULL を渡します。

于 2012-08-12T19:43:09.200 に答える