65.9K
CodeProject 正在变化。 阅读更多。
Home

我的第一个 Win32 UI

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.59/5 (8投票s)

2013年1月3日

CPOL

3分钟阅读

viewsIcon

22627

downloadIcon

8

一个使用 Win32 API 展示简单对话框的示例应用程序。

为什么

本文是在我为调查 Windows 平台上的音频生成技术而进行的工作中产生的,它描述了我的一项核心需求,即使用 Win32 API 创建和管理 Windows 应用程序 UI。

我可以有很多种方法来完成这项工作,但对于这项工作,我想深入研究 API 的工作原理,以了解技术并开发我自己的资源,所以我跳过了许多可用的 UI 库,转而使用 API 进行直接 UI 操作。

那里有很多文档完善的例子,但似乎没有一个符合我迫切的需求,即一个应用程序打开一个带有按钮和列表框的简单表单,仅此而已,一些我可以重复使用和构建的东西。

如何操作

跳过详细的解释(有很多可用的解释),直接进入代码,我想做的第一件事是设计 UI 的呈现方式。

再次使用 Visual Studio 2010,对于完整版本,有一个内置的编辑器,对于精简版,您将不得不使用外部工具,例如 Resedit,如这里所述。这些编辑器允许您创建表单或窗口设计,并从中生成所谓的资源脚本。正是这个资源脚本(.rc 文件)随后被包含在主项目中,以描述表单并管理对其内部元素的访问。

在不深入探讨太多细节的情况下,对于我的示例,我为我的应用程序创建了一个简单的对话框表单,其中包含一个按钮和一个列表框,如下所示

从这里开始,在保存对话框时,该工具会创建两个文件,一个.rc文件,另一个名为 resources.h。这些需要包含在主项目中。

.rc 文件是实际描述控件的脚本,对于上面的表单,它应该看起来像这样

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"

//
// Dialog resources
//
LANGUAGE 0, SUBLANG_NEUTRAL
IDD_DIALOG1 DIALOG 0, 0, 277, 161
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | 
      WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Sample Win32"
FONT 8, "Ms Shell Dlg"
{
    DEFPUSHBUTTON   "Show List", IDSHOWLIST, 22, 17, 46, 14
    LISTBOX         IDC_LIST1, 23, 47, 228, 96, WS_TABSTOP | WS_VSCROLL | 
                    LBS_NOINTEGRALHEIGHT | LBS_SORT | LBS_NOTIFY
}

进入代码的主要部分。应用程序的入口点是 WinMain 函数。在这个函数中,上面定义的窗口被创建为一个对话框,如下所示

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

请注意,在 DialogBox 调用中,MAKEINTRESOURCE 指的是先前创建的要在屏幕上显示的资源的名称。还要注意对DlgProc的引用。这是处理来自对话框窗口的回调的函数,即来自用户的响应。

DlgProc处理从对话框接收到的响应,称为消息,如下所示

BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch(Message)
    {
        case WM_INITDIALOG:
            // This is where we set up the dialog box, and initialise any default values

        break;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case IDSHOWLIST:
                {
                    HWND hListBox = ::GetDlgItem(hwnd, IDC_LIST1);
                    for (int i = 0 ; i < 8 ; i++)
                    SendMessage( hListBox, LB_ADDSTRING, 0, (LPARAM)("Modes List Box"));
                }
                break;
            }
        break;
        case WM_CLOSE:
            EndDialog(hwnd, 0);
        break;
        default:
            return FALSE;
    }
    return TRUE;
}

在这里,代码查看返回的 Message 的值。如果这是WM_COMMAND,则表示用户以某种方式与窗口交互。实际参与该交互的控件可以通过查看wParam的值来派生,并且将是Resource.h中定义的值之一。在这种情况下,如果单击了该按钮,则WM_COMMAND将被设置为按钮的 ID,IDSHOWLIST,并且可以编写代码来处理此消息。

这里的简单示例代码用多行文本数据填充列表框。为此,找到了 ListBox 句柄的引用(请注意,所有控件实际上都被视为它们自己的窗口)。给定此句柄,消息可以发送到 ListBox,在本例中是添加文本,由LB_ADDSTRING参数指示。

© . All rights reserved.