【问题标题】:Win32: How to create a ListBox control using the CreateWindowExW() function?Win32:如何使用 CreateWindowExW() 函数创建 ListBox 控件?
【发布时间】:2011-05-27 06:48:26
【问题描述】:

我浏览过多个站点、文档和教程,它们都说相同,即任何控件都只不过是 Win32 API 中的一个窗口,因此可以使用 CreateWindowExW() 函数创建一个ListBox 主应用程序窗口上的控制/窗口。

虽然我知道所有控件都是具有不同 dwStyle 的窗口的概念,但我很难找到如何实例化 ListBox 控件的方法。

我遇到了一个教程,其中编写了一个对话框以在其声明中指定 LISTBOX,如下所示:

// resource.h
#define IDD_MAIN                        101
#define IDC_TEXT                        1000
#define IDC_NUMBER                      1001
#define IDC_LIST                        1002
#define IDC_ADD                         1003
#define IDC_CLEAR                       1004
#define IDC_REMOVE                      1005
#define IDC_SHOWCOUNT                   1006

// .rc resource file
IDD_MAIN DIALOG DISCARDABLE  0, 0, 207, 156
    STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
    CAPTION "Controls One"
    FONT 8, "MS Sans Serif"
BEGIN
    LTEXT           "Add",IDC_STATIC,7,10,14,8
    EDITTEXT        IDC_TEXT,25,7,120,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_NUMBER,150,7,21,14,ES_NUMBER
    LTEXT           "times.",IDC_STATIC,177,10,23,8
    LISTBOX         IDC_LIST,7,25,138,106,LBS_NOINTEGRALHEIGHT | 
                    LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
    PUSHBUTTON      "&Add",IDC_ADD,150,30,50,14
    PUSHBUTTON      "&Remove",IDC_REMOVE,150,47,50,14
    PUSHBUTTON      "&Clear",IDC_CLEAR,150,63,50,14
    LTEXT           "This item was added",IDC_STATIC,7,141,66,8
    CTEXT           "-",IDC_SHOWCOUNT,77,141,32,8
    LTEXT           "times",IDC_STATIC,114,141,17,8
END

并像这样在他的 C 程序中使用它:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    return DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc);
}

现在,我能够做到并完全理解这些概念。除此之外,我希望能够创建和设计我的主应用程序窗口以添加ListBox 控件。本教程示例不使用CreateWindowExW() 函数来创建控件,而是创建一个实际上将是主应用程序窗口的对话框。

1 - 任何关于如何在代码中将ListBox 控件添加到主窗口的线索?

我考虑在处理 WM_CREATE 消息时创建它。

2 - 这是个好主意吗?

3 - 在这种情况下最佳实践/方法是什么?

【问题讨论】:

  • 编写这种代码从来都不是一个好主意,有很多优秀的类库可以消除乏味和错误。想学Win32的汇编语言也没关系。不过,这不是一个非常引人注目的问题。
  • 我不打算使用 Win32 编写完整的企业系统。我喜欢 C,并且一直想了解更多关于 Win32 的信息。回到我开始学习编程的时候,Win32 对我来说太复杂了,无法学习。今天,我完全理解了背后的概念,所以我更容易学习。由于 .NET Framework 是基于 Win32 的,我希望了解更多。

标签: c listbox winapi createwindow


【解决方案1】:

为了在 Win32 中动态创建控件,您需要以下代码:

HWND hBtn, hLabel, hListbox, hTextBox;

void InitializeComponent(HWND hWnd) {
    HINSTANCE hInstance = GetModuleHandle(NULL);

    // Adding a Button.
    hBtn = CreateWindowExW(WS_EX_APPWINDOW,
        L"BUTTON", NULL,
        WS_CHILD | WS_VISIBLE,
        327, 7, 70, 21,
        hWnd, NULL, hInstance, NULL);        

    SetWindowTextW(hBtn, L"&Button");

    // Adding a Label.
    hLabel = CreateWindowExW(WS_EX_CLIENTEDGE,
        L"STATIC", NULL,
        WS_CHILD | WS_VISIBLE,
        7, 7, 50, 21,
        hWnd, NULL, hInstance, NULL);

    SetWindowTextW(hLabel, L"Label:");

    // Adding a ListBox.
    hListBox = CreateWindowExW(WS_EX_CLIENTEDGE,
        L"LISTBOX", NULL,
        WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL,
        7, 35, 300, 200,
        hWnd, NULL, hInstance, NULL);

    // Adding a TextBox.
    hTextBox = CreateWindowExW(WS_EX_CLIENTEDGE,
        L"EDIT", NULL,
        WS_CHILD | WS_VISIBLE | ES_AUTOVSCROLL,
        62, 7, 245, 21,
        hWnd, NULL, hInstance, NULL);

    SetWindowTextW(hTextBox, L"Input text here...");
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
    switch (Msg) {
        case WM_CREATE:
            InitializeComponent(hWnd);
            break;            
        default:
            return DefWindowProcW(hWnd, Msg, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
    // Declaring, defining, registering and creating window here...
    // Note that each Window/Control has to have its own Message handling function.
}

【讨论】:

  • 你真的应该纠正这个问题,否则这个问答造成的伤害大于它的帮助。我假设您在 2013 年 6 月 25 日之前再次发布此代码而没有再次查看代码,并再次在 cplusplus 寻求帮助。我也想看看真正的解决方案:)
  • 对不起,我可能把你误认为是这里的其他人了。但是,此代码肯定包含错误,例如在列表框控件中使用编辑控件样式和混淆字符串类型。
  • 我想知道你怎么会把我和其他人混淆。这段代码不是 C++,而是 Win32。
  • 措辞正确,这实际上是 C++(或 C?)并且它使用 Win32 API。我自己只是在寻找这个问题的答案,并在此处和cplusplus.com/forum/general/105127 上找到了这段代码,其中有人评论它有几个错误。
  • 我明白了。谢谢你通知我。此外,这个问题的意图实际上只是想知道如何在表单上绘制一个ListBox 控件,这是这段代码允许的。至于在生产代码中使用ListBox 控件的动态,我同意这可能无法正常工作。因为我的目的是让自己真正熟悉 Win32,所以这段代码做到了,因此,我接受了自己的答案。也许您应该考虑发布您的答案,以便引起注意。 =)
【解决方案2】:
HWND hListBox; // Handle for list box control

hListBox = CreateWindowEx(
  WS_EX_CLIENTEDGE, // extended window styles
  "LISTBOX", // list box window class name
  NULL,
  WS_CHILD | WS_VISIBLE, // window styles
  7,   // horizontal position
  35,  // vertical position
  300, // width
  200, // height
  hWnd,
  NULL,
  hInstance,
  NULL
);

if (!hListBox){
  // failed to create list box window - take actions ...
}

【讨论】:

  • 这与我在答案中提供的代码有什么不同,告诉我?
  • 所有对创建列表框控件不重要的东西都被删除了。使用 CreateWindowEx() 代替 CreateWindowExW() 和 L"LISTBOX" 演员表,这增加了简单性。编辑控件样式 ES_VSCROLL 和 ES_AUTOVSCROLL 被忽略了,因为它们不能用于列表框控件(据我所知)。添加了错误检查,这对于不容忍任何缺失控件的界面非常重要。
  • @Sam:什么演员?而您的将不适用于定义了UNICODE 的项目。接受普通非 Unicode 字符串的函数名为 CreateWindowExA
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-29
  • 1970-01-01
相关资源
最近更新 更多