下载source - 100 Kb
(单行输入框)
(多行输入框)
介绍
有一天,我正在写一个小窗口工具,想要得到一些来自用户的输入。因为我的应用程序并不是一个MFC,也不是一个控制台应用程序,据我所知,没有简单的方法来获取来自用户的输入。Windows API相当的工作给我们的对话框()函数,但不像InputBox函数。因为我想我的应用程序保持苗条和独立的,我决定调查关于如何使用对话框不使用资源和不引入过多的代码。
因此,Win32InputBox图书馆诞生了。
在这篇文章中,我将介绍如何创建和使用没有创建对话框资源或使用MFC对话框。我们将使用这种技术来创建一个InputBox()函数,它类似于VB的InputBox()。
背景
重要的是读者熟悉Windows消息,和窗口或对话框过程机制。尽管如此,我将会给初学者一个简单的介绍。
介绍对话框——古典的方式
目前,创建一个对话框驱动的应用程序中,您有很多选择。我将列出最受欢迎的方法:
基于MFC对话框的应用程序(可以由向导生成)。
普通的Win32 API——设计师使用IDE的对话框。
平原Win32 API——不使用对话框设计,相反,使用代码来创建所有的控制和对话框窗口。
每一个上面提到的方法有自己的优点和缺点,但这超出了本文的范围。现在正如所承诺的,这里是一个小概述每个机制是如何工作的。
我们开始与普通的Win32 API(使用对话框设计):
设计部分:
我们开始设计我们的对话框编辑器。
我们创建控件(按钮、文本框、…)。
我们将IDs分配给控件。
编码的部分:
我们写WindowProc(),它将处理所有相关的事件我们的对话框。
我们调用合适的对话框创建方法(CreateDialog()的家庭,或对话框()函数的家庭)。
如果你不使用的对话框设计师,你必须在代码中创建的控件通过调用CreateWindow()函数。
至于基于MFC对话框的应用程序,这个概念是相似的,但是一切都包装成整齐的类。所以,你所要做的是:
设计使用编辑器对话框。
CMyDialog子类CDialog说。
从它派生出子类类绑定到所需的对话ID。
覆盖需要CDialog的方法来处理消息和事件。
介绍对话框模板
一个对话框模板是什么?这是一个结构,定义了一个给定的风格和尺寸对话框。一个对话框模板定义通过DLGTEMPLATE结构中发现的窗口标题。有一个扩展版的这个结构,使后者过时了。DLGTEMPLATEEX不是在头文件中定义的,但在MSDN描述。扩展对话框模板(DLGTEMPLATEEX)是新的,并引入了更多的功能。
一个对话框模板是足以描述对话框,而不是对话框项目,因此DLGITEMTEMPLATE /交货的结构。这些DLGITEMTEMPLATE[例]结构将定义对话框内的物品。
当你使用对话框编辑器(在vc++ IDE),你是视觉构建对话框模板和项目的对话框模板(然而,在源代码形式)。当你编译你的应用程序中,单独编译使用的资源RC.EXE(资源编译器)的工具,这将产生r(二进制文件)的.RC(文本文件),最后一切都会联系在一起产生一个可执行模块。
这里就是DLGTEMPLATE DLGITEMTEMPLATE .RC文件中描述:隐藏,复制CodeIDD_INPUTBOX DIALOGEX 22, 17, 231, 109
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS |
WS_CAPTION | WS_SYSMENU
CAPTION “Win32InputBox”
FONT 8, “MS Shell Dlg”, 700, 0, 0x0
BEGIN
LTEXT “Prompt:”,IDC_INPUTBOX_PROMPT,6,4,157,
33,SS_NOPREFIX
EDITTEXT IDC_INPUTBOX_DLG_EDIT1,6,37,216,14,
ES_AUTOHSCROLL
EDITTEXT IDC_INPUTBOX_DLG_EDIT2,6,55,216,49,
ES_MULTILINE | ES_AUTOHSCROLL |
ES_WANTRETURN | WS_VSCROLL
DEFPUSHBUTTON “OK”,IDOK,171,4,51,14,WS_GROUP
PUSHBUTTON “CANCEL”,IDCANCEL,171,21,51,14,WS_GROUP
LTEXT “”,IDC_STATIC,0,39,8,8,NOT WS_VISIBLE
END
彻底理解这个源文件,请参考MSDN(检查参考下文)。
但是,我希望你要注意以下几点:
的数字表示尺寸和位置。
的IDXXXX表示id。这些id”中定义的资源。h”文件。
“LTEXT”的命令,“EDITTEXT”等……创建指定的控制。
常量WS_VISIBLE风格ES_MULTILINE或DS_MODALFRAME,等等……
如果你感兴趣如何r文件的样子,我有一个小的十六进制转储编译结构:
这里有一个“资源。h”(部分)的样子:隐藏,复制Code#define IDD_INPUTBOX 103
#define IDC_INPUTBOX_PROMPT 1000
#define IDC_INPUTBOX_DLG_EDIT1 1001
#define IDC_INPUTBOX_DLG_EDIT2 1002
#define IDC_STATIC -1
请注意,RES文件不仅描述了你的对话框,但也.RC文件中的所有物品(图标,字符串表等)。从资源文件包含大量的资源项目,所有定义为特定的id和资源类型,我们需要一种方法来选择给定的资源并使用它。这就是为什么我们有FindResource()和其他资源管理api。
这个小程序将说明如何创建一个对话框中定义其ID resource.h IDD_MYDLG:隐藏,复制Code#include <windows.h>
#include “resource.h”
int main()
{
HMODULE hModule = ::GetModuleHandle(0);
HINSTANCE hInst = hModule;
HRSRC hrsrc = ::FindResource(hModule,
MAKEINTRESOURCE(IDD_MYDLG), RT_DIALOG);
HGLOBAL hglobal = ::LoadResource(hModule, hrsrc);
::DialogBoxIndirectParam(hInst,
(LPCDLGTEMPLATE) hglobal, 0, 0, 0);
return 0;
}
注意我们如何通过“hglobal”“LPCDLGTEMPLATE”。这是指针编译后的对话框模板earlie讨论这段代码没有通过对话框过程,因此对话框将不会响应关闭消息或类似的消息,您将不得不杀死该进程或编写适当的对话框过程。
我们可以编写的一个简单对话程序是:隐藏复制CodeLRESULT CALLBACK dlgProc(HWND hDlg, UINT Msg,
WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_CLOSE:
::EndDialog(hDlg, IDOK);
return TRUE;
}
return 0;
}
然后我们调整调用为:Hide 复制Code::DialogBoxIndirectParam(hInst, (LPCDLGTEMPLATE) hglobal,
0, (DLGPROC)dlgProc, 0);
DlgResToDlgTemplate工具
在编写Win32Inputbox库的过程中,我开发了一个名为“DlgResToDlgTemplate”的小工具。这个工具的唯一目的是从二进制文件(现在是编译形式)中获取对话框资源,并将其转储为C字符数组。在提取对话框模板之后,我们可以在自己的应用程序中使用它。
一个简单的例子是,在我们自己的简单应用程序中使用记事本. exe模板。
使用:Hide 从notepad.exe中提取模板d:\windows\system32\notepad.exe 14 n。hHide,复制CodeDlgResToDlgTemplate v1.0 © <
成功生成n.h(1195字节)!
现在我们有了n。h”是记事本.exe“Goto line”对话框的模板,我们可以将上面提到的示例代码修改为:收缩,复制Codestatic unsigned char dlg_14[] =
{
0 xc0 0 x20 0 xc8, 0 x80 0 x00, 0 x00, 0 x00, 0 x00,
0 x04 0 x00 0 x00 0 x00, 0 x00, 0 x00, 0 xb4 0 x00, 0 x39,
0 x00, 0 x00 0 x00 0 x00, 0 x00, 0开发,x47 0 x00, 0 x6f,
0 x00 0 x74 0 x00 0 x6f, 0 x00, 0 x20, 0 x00, 0 x6c,
0 x00 0 x69 0 x00 0 x6e, 0 x00, 0 x65 0 x00, 0 x00,
0 x00 (0 x00 0 x4d, 0 x00, 0 x53 0 x00, 0 x20,
0 x00 0 x53 0 x00 0 x68, 0 x00, 0 x65 0 x00, 0 x6c,
0 x00 0 x6c 0 x00 0 x20的,0 x00, 0 x44 0 x00, 0 x6c,
0 x00 0 x67 0 x00 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00 0 x02 0×50 0 x00, 0 x00, 0 x00, 0 x00, 0 x07,
0 x00 0 x09 0 x00 0 x32, 0 x00, 0 x0a 0 x00, 0 xb0,
0 x04 0 xff 0 xff 0 x82, 0 x00, 0 x26 0 x00, 0 x4c,
0 x00 0 x69 0 x00 0 x6e, 0 x00, 0 x65 0 x00, 0 x20,
0 x00 0 x4e 0 x00 0 x75, 0 x00, 0 x6d 0 x00, 0 x62,
0 x00 0 x65 0 x00 0 x72, 0 x00, 0 x3a 0 x00, 0 x00,
0 x00, 0 x00 0 x00 0 x80, 0 x00, 0 x81 0×50 0 x00,
0 x00, 0 x00 0 x00 0 x37, 0 x00, 0 x07 0 x00, 0 x39,
0 x00 0 x0c 0 x00 0 x02, 0 x01, 0 xff, 0 xff, 0 x81,
0 x00, 0 x00 0 x00 0 x00, 0 x00, 0 x00, 0 x00, 0 x01,
0 x00 0 x01 0×50 0 x00, 0 x00, 0 x00, 0 x00, 0 x07,
0 x00 0将0 x00 0 x32, 0 x00, 0 x0e 0 x00, 0 x01,
0 x00 (0 xff 0 xff 0 x80, 0 x00, 0 x4f 0 x00, 0 x4b,
0 x00, 0 x00 0 x00 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00 0 x01 0×50 0 x00, 0 x00, 0 x00, 0 x00, 0 x4e,
0 x00 0将0 x00 0 x32, 0 x00, 0 x0e 0 x00, 0 x02,
0 x00 (0 xff 0 xff 0 x80, 0 x00, 0 x43 0 x00, 0 x61,
0 x00 0 x6e 0 x00 0 x63, 0 x00, 0 x65 0 x00, 0 x6c,
0 x00 0 x00 0 x00, 0 x00 0 x00
};
空白show_template_dlg ()
{
:: DialogBoxIndirectParam((实例句柄)::GetModuleHandle (0)
(LPCDLGTEMPLATE) dlg_14, 0, (DLGPROC) DLGPROC, 0);
}
希望到目前为止一切都很清楚。接下来,我们将看到使用对话框模板来创建小的(自包含的)函数是多么实用。
CWin32InputBox类概述
在介绍了此任务所需的所有概念之后,现在我们可以讨论CWin32Inputbox类的构造。
简而言之,CWin32InputBox::InputBox():
定义处理OK和CANCEL按钮的适当对话框过程。
定义一个WM_INITDIALOG处理程序来正确初始化对话框。
有了需要的对话框模板,命名为“definputbox_dlg”,我们可以:
调用DialogBoxIndirectParam()来显示对话框。
根据模态对话框的返回值执行一些操作。
这个类导出两个静态方法:复制Codestatic INT_PTR InputBoxEx(WIN32INPUTBOX_PARAM *);
static INT_PTR InputBox(LPCTSTR szTitle,
LPCTSTR szPrompt,
LPTSTR szResult,
DWORD nResultSize,
bool bMultiLine = false,
HWND hwndParent = 0);
您可以简单地调用InputBox方法:复制CodeCWin32InputBox::InputBox(“hello”, “what?”, buf, 100, false);
生产类似于:
扩展版本使用WIN32INPUTBOX_PARAM结构来允许您定制输入框。因此,要在您的项目中使用这个类,您只需添加“Win32InputBox.cpp/”。支持你的项目。不需要资源或任何东西。
您可以自由使用zlib/libpng许可证下的代码;检查“Win32InputBox。h”文件。
的兴趣点
学习对话框模板很有趣,编写可重用的CWin32InputBox类更有趣。希望您喜欢并从本文中学到了东西。如果你给我一个低评级,我会很感激给我一个评论,告诉我如何改进我的文章。
在结束这篇文章之前,我想给那些不知道的人一个小提示:你可以使用你的Visual Studio IDE查看其他二进制文件资源。只需按CTRL+O,找到一个Win32 PE文件,并打开它!
参考文献
MSDN→Win32和COM开发->工具→平台SDK工具->SDK工具→资源工具→资源编译器→资源定义语句。
MSDN→CreateWindowEx()函数。
MSDN→使用资源。
MSDN→DLGTEMPLATEEX结构。
本文转载于:http://www.diyabc.com/frontweb/news3611.html