使用对话框模板创建一个InputBox()在C + +

(单行输入框) (多行输入框) 介绍 有一天,我正在写一个小窗口工具,想要得到一些来自用户的输入。因为我的应用程序并不是一个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文件中描述:隐藏,复制Code

IDD_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讨论这段代码没有通过对话框过程,因此对话框将不会响应关闭消息或类似的消息,您将不得不杀死该进程或编写适当的对话框过程。 我们可以编写的一个简单对话程序是:隐藏复制Code

LRESULT 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:windowssystem32 otepad.exe 14 n。hHide,复制CodeDlgResToDlgTemplate v1.0 (c) < 成功生成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()来显示对话框。 根据模态对话框的返回值执行一些操作。 这个类导出两个静态方法:复制Code

static INT_PTR InputBoxEx(WIN32INPUTBOX_PARAM *);
static INT_PTR InputBox(LPCTSTR szTitle, 
                        LPCTSTR szPrompt, 
                        LPTSTR szResult, 
                        DWORD nResultSize,
                        bool bMultiLine = false,
                        HWND hwndParent = 0);

您可以简单地调用InputBox方法:复制Code

CWin32InputBox::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

原文地址:https://www.cnblogs.com/Dincat/p/13461207.html