我的第一个 Win32 UI






4.59/5 (8投票s)
一个使用 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
参数指示。