030 在DLL中产生对话框的方法一(Win32 DLL)

Post date: 2015/4/20 上午 03:46:13

什么是Dll?

Stands for "Dynamic Link Library." A DLL (.dll) file contains a library of functions and other information that can be accessed by a Windows program. When a program is launched, links to the necessary .dll files are created. If a static link is created, the .dll files will be in use as long as the program is active. If a dynamic link is created, the .dll files will only be used when needed. Dynamic links help programs use resources, such as memory and hard drive space, more efficiently.

对话框:

对话框可以分为modal和modeless两种。

在Win32 Dll中创建modal对话框。

在一个Win32Dll中创建modal对话框非常简单,我们都知道,Win32函数DialogBox能够创建一个modal对话框,并且modal对话框的消息是独立于主程序消息循环的,所以可以直接在Dll内部建立对话框自己的窗口过程。下面就是一个在Win32 Dll中创建modal对话框的示例:

//name: Modal_Dialog.cpp

#include<windows.h>

#include"resource.h"

BOOL CALLBACK DlgProc(HWND hwnd,UINT Msg,WPARAM wParam,LPARAM lParam)

{

switch(Msg)

{

case WM_INITDIALOG:

return TRUE;

case WM_COMMAND:

switch(wParam)

{

case IDOK:

MessageBox(NULL,"这是一个modal对话框的例子","提示",MB_OK);

EndDialog(hwnd, 0);

return TRUE;

}

break;

}

return FALSE;

}

extern"C" __declspec(dllexport) void ShowDialog()

{

HINSTANCE hinst;

hinst=LoadLibrary("Modal_Dialog.dll"); //获取库所在的实例句柄

DialogBox(hinst,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DlgProc);

FreeLibrary(hinst);

}

//name: Test.cpp

……

typedef void (*fp)();

HINSTANCE hDll;

fp Show;

hDll = LoadLibrary("Modal_Dialog.dll");

Show = (fp)GetProcAddress(hDll,"ShowDialog");

(*Show)();

FreeLibrary(hDll);

……

在Win32 Dll 中创建modeless对话框。

与modal对话框不同,modeless对话框的消息是要经过主程序消息循环的,这样一来,就必须在调用该Dll的主程序中处理对话框的消息循环,这就无法达到利用Dll来完成组件化开发的要求。其实我们可以人为的Modeless对话框创建一个窗口类,我们知道窗口过程是属于窗口类的,这样一来就有了主窗口的消息循环。

//name: Modeless_Dialog.cpp

#include <windows.h>

#include"resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

BOOL CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM) ;

extern"C" int __declspec(dllexport) ShowDialog()

{

static TCHAR szAppName[] = TEXT ("Modeless_Dialog") ;

HWND hwnd ;

MSG msg ;

WNDCLASS wndclass ;

HINSTANCE hInstance;

HWND hDialog;

hInstance = LoadLibrary("Modeless_Dialog.dll");

wndclass.style = CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc = WndProc ;

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = DLGWINDOWEXTRA ; // Note!

wndclass.hInstance = hInstance ;

wndclass.hIcon = LoadIcon (hInstance, szAppName) ;

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ;

wndclass.lpszMenuName = NULL ;

wndclass.lpszClassName = szAppName ;

hwnd = CreateWindow (szAppName, TEXT ("Modeless_Dialog"),

WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, NULL, hInstance, NULL) ;

// ShowWindow (hwnd, iCmdShow) ; //并不在这里显示主窗口

// UpdateWindow (hwnd) ;

hDialog = CreateDialog (hInstance, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, DlgProc) ;

while (GetMessage (&msg, NULL, 0, 0))

{

if(hDialog==0||!IsDialogMessage(hDialog,&msg))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

}

return msg.wParam ;

}

BOOL CALLBACK DlgProc (HWND hDlg, UINT message,

WPARAM wParam, LPARAM lParam)

{

switch(message)

{

case WM_INITDIALOG :

return true;

case WM_COMMAND:

switch(wParam)

{

case(IDOK):

MessageBox(NULL,"这是一个modeless对话框的例子","提示",MB_OK);

DestroyWindow(hDlg);

PostQuitMessage (0) ;

return TRUE;

}

}

return FALSE;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

switch (message)

{

case WM_DESTROY:

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc (hwnd, message, wParam, lParam) ;

}

CreateDialog用来创建窗口,并且对话框模板要指定visible属性为True,只有这样才能显示对话框.

if(hDialog==0||!IsDialogMessage(hDialog,&msg))这一句是起消息分流作用的,对于属于对话框的消息一律交给对话框过程DlgProc来处理。

处理对话框的退出一定要使用DetroyWindow函数,并且要发送一个退出消息,使那个没有显示的主窗口也能够退出消息循环,不至于造成内存泄露。