自己项目中CreateDialog的用法
项目里面用的一个API被人说没弹出的消息窗体存在问题,没法多个消息传出以及新消息在前端显示。
没办法只能新建一个项目采用Windows SDK,然后使用CreateDialog来创建一个非模式对话框,
然后通过发送WM_COPYDATA从我的后台线程发送消息到这个应用程序,再传到相应的对话框上。(其他的进程共享如SOCKET,管道,油槽,共享内存等,就不介绍了)
以上经过测试可行,如果要用其他的方式,一样需要使用到windows消息,所以只使用WM_COPYDATA的话还是比较稳妥的方法(对小数据来说),注意最好不要在WM_COPYDATA中的结构体中传递指针,因为2个进程间的指针很有可能是不同的。
思路是有了,但是遇到一些问题, 创建对话框消息处理的函数的最后使用了DefDlgProc,然后一下就报错,上网找了一下,在国外的某个页面发现了其详细解释,意思大概是这样的:
我们接受到的都是基于窗口的消息, 但是DefDlgProc处理的是对话框消息,也就是他们的类不同,所以会没法处理。那就不处理吧呵呵。
具体的代码如下:
#pragma once
#include "resource.h"
HWND CreateMessageDialog();
typedef struct tagUniMessage
{
wchar_t title[32];
wchar_t body[1024];
}UniMessage,*PUniMessage;
LRESULT CALLBACK ReversiDialogProc(HWND hDlg, UINT Msg,WPARAM Param1,LPARAM Param2);
DWORD tmessage( PUniMessage);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
#include "resource.h"
HWND CreateMessageDialog();
typedef struct tagUniMessage
{
wchar_t title[32];
wchar_t body[1024];
}UniMessage,*PUniMessage;
LRESULT CALLBACK ReversiDialogProc(HWND hDlg, UINT Msg,WPARAM Param1,LPARAM Param2);
DWORD tmessage( PUniMessage);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// WinNotifyStd.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "WinNotifyStd.h"
//自定义消息
#define UNI32_MESSAGE WM_USER+12345
//全局变量
HINSTANCE g_hInst;
//总的显示窗体
HWND hDlgs[1024]={NULL};
//当前计数
long count = 0;
//锁
HANDLE hlock=CreateEvent(NULL,false,true,NULL);
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstace,LPSTR lpCmdLine,int nCmdShow)
{
// TODO: 在此放置代码。
int err = 0;
g_hInst = hInstance;
MSG msg;
//创建窗口类,因为我们的窗口不显示,所以可以使用如下的设置
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"WINNOTIFYSTD";
wcex.hIconSm = NULL;
RegisterClassEx(&wcex);
//创建之后不显示
HWND hWnd;
hWnd = CreateWindow(L"WINNOTIFYSTD", L"WINNOTIFYSTD", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
//消息循环
while ( GetMessage( &msg,NULL,0,0) )
{
//进入临界区,然后对每个对话框查询消息状态
BOOL isDialog=false;
WaitForSingleObject(hlock,INFINITE);
for( int i =0 ;i<1024;i++)
{
if( hDlgs[i]!=NULL && IsDialogMessage(hDlgs[i],&msg) )
{
isDialog=true;
break;
}
}
SetEvent(hlock);
//如果不是对话框消息,那么是自己的消息
if(!isDialog)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
DWORD tmessage( PUniMessage msg)
{
HWND hWnd=CreateMessageDialog();
WaitForSingleObject( hlock,INFINITE);
hDlgs[count++]=hWnd;
//窗体资源回收
if(count==1024)
{
int rest=0;
for(int i=0;i<1024;i++)
{
if( hDlgs[i] ==NULL )
{
for(int j=i+1;j<1024;j++)
{
if(hDlgs[j] != NULL)
{
hDlgs[i]=hDlgs[j];
hDlgs[j]=NULL;
rest++;
}
}
}
else
{
rest++;
}
}
count = rest;
}
SetEvent(hlock);
wchar_t * tmpTitle = NULL;
wchar_t * tmpBody = NULL;
ShowWindow(hWnd,TRUE);
BringWindowToTop(hWnd);
//发个自定义消息给自己的窗体
SendMessage( hWnd,UNI32_MESSAGE,(WPARAM)msg,NULL);
return 0;
}
HWND CreateMessageDialog()
{
//创建对话框使用自定义消息处理函数
//IDD_ABOUTBOX
return CreateDialogW(g_hInst,MAKEINTRESOURCE(IDD_ABOUTBOX),NULL,(DLGPROC)ReversiDialogProc);
}
LRESULT CALLBACK ReversiDialogProc(HWND hDlg, UINT Msg,WPARAM wParam,LPARAM lParam)
{
switch(Msg)
{
case UNI32_MESSAGE:
{
SetWindowTextW(hDlg,(LPCWSTR)lParam);
PUniMessage msg = (PUniMessage)wParam;
SetDlgItemText((HWND)hDlg,IDC_EDIT1,msg->body);
SetDlgItemText((HWND)hDlg,IDC_EDIT2,msg->title);
break;
}
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case IDOK:
case IDCANCEL:
//
DestroyWindow(hDlg);
CloseHandle(hDlg);
// WaitForSingleObject(hlock2,INFINITE);
for( int i=0;i<1024;i++)
{
if(hDlgs[i] == hDlg)
{
hDlgs[i] = NULL;
break;
}
}
// SetEvent(hlock2);
return TRUE;
}
break;
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
break;
default:
// 注意不要使用DefDlgProc,因为很简单,我们接受到的都是基于窗口的消息
// 但是DefDlgProc处理的是对话框消息,所以会没法处理,这里只要简单返回无法处理的false就好了。
// should not call DefDlgProc
// return DefDlgProc(hDlg, Msg, wParam, lParam);
break;
}
return FALSE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_COMMAND:
{
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
}
case WM_COPYDATA:
{
//直接设置,因为发送数据的是采用SendMessage
PCOPYDATASTRUCT myPcd = (PCOPYDATASTRUCT)lParam;
tmessage((PUniMessage)myPcd->lpData);
break;
}
case WM_PAINT:
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//
#include "stdafx.h"
#include "WinNotifyStd.h"
//自定义消息
#define UNI32_MESSAGE WM_USER+12345
//全局变量
HINSTANCE g_hInst;
//总的显示窗体
HWND hDlgs[1024]={NULL};
//当前计数
long count = 0;
//锁
HANDLE hlock=CreateEvent(NULL,false,true,NULL);
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstace,LPSTR lpCmdLine,int nCmdShow)
{
// TODO: 在此放置代码。
int err = 0;
g_hInst = hInstance;
MSG msg;
//创建窗口类,因为我们的窗口不显示,所以可以使用如下的设置
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"WINNOTIFYSTD";
wcex.hIconSm = NULL;
RegisterClassEx(&wcex);
//创建之后不显示
HWND hWnd;
hWnd = CreateWindow(L"WINNOTIFYSTD", L"WINNOTIFYSTD", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
//消息循环
while ( GetMessage( &msg,NULL,0,0) )
{
//进入临界区,然后对每个对话框查询消息状态
BOOL isDialog=false;
WaitForSingleObject(hlock,INFINITE);
for( int i =0 ;i<1024;i++)
{
if( hDlgs[i]!=NULL && IsDialogMessage(hDlgs[i],&msg) )
{
isDialog=true;
break;
}
}
SetEvent(hlock);
//如果不是对话框消息,那么是自己的消息
if(!isDialog)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
DWORD tmessage( PUniMessage msg)
{
HWND hWnd=CreateMessageDialog();
WaitForSingleObject( hlock,INFINITE);
hDlgs[count++]=hWnd;
//窗体资源回收
if(count==1024)
{
int rest=0;
for(int i=0;i<1024;i++)
{
if( hDlgs[i] ==NULL )
{
for(int j=i+1;j<1024;j++)
{
if(hDlgs[j] != NULL)
{
hDlgs[i]=hDlgs[j];
hDlgs[j]=NULL;
rest++;
}
}
}
else
{
rest++;
}
}
count = rest;
}
SetEvent(hlock);
wchar_t * tmpTitle = NULL;
wchar_t * tmpBody = NULL;
ShowWindow(hWnd,TRUE);
BringWindowToTop(hWnd);
//发个自定义消息给自己的窗体
SendMessage( hWnd,UNI32_MESSAGE,(WPARAM)msg,NULL);
return 0;
}
HWND CreateMessageDialog()
{
//创建对话框使用自定义消息处理函数
//IDD_ABOUTBOX
return CreateDialogW(g_hInst,MAKEINTRESOURCE(IDD_ABOUTBOX),NULL,(DLGPROC)ReversiDialogProc);
}
LRESULT CALLBACK ReversiDialogProc(HWND hDlg, UINT Msg,WPARAM wParam,LPARAM lParam)
{
switch(Msg)
{
case UNI32_MESSAGE:
{
SetWindowTextW(hDlg,(LPCWSTR)lParam);
PUniMessage msg = (PUniMessage)wParam;
SetDlgItemText((HWND)hDlg,IDC_EDIT1,msg->body);
SetDlgItemText((HWND)hDlg,IDC_EDIT2,msg->title);
break;
}
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case IDOK:
case IDCANCEL:
//
DestroyWindow(hDlg);
CloseHandle(hDlg);
// WaitForSingleObject(hlock2,INFINITE);
for( int i=0;i<1024;i++)
{
if(hDlgs[i] == hDlg)
{
hDlgs[i] = NULL;
break;
}
}
// SetEvent(hlock2);
return TRUE;
}
break;
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
break;
default:
// 注意不要使用DefDlgProc,因为很简单,我们接受到的都是基于窗口的消息
// 但是DefDlgProc处理的是对话框消息,所以会没法处理,这里只要简单返回无法处理的false就好了。
// should not call DefDlgProc
// return DefDlgProc(hDlg, Msg, wParam, lParam);
break;
}
return FALSE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_COMMAND:
{
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
}
case WM_COPYDATA:
{
//直接设置,因为发送数据的是采用SendMessage
PCOPYDATASTRUCT myPcd = (PCOPYDATASTRUCT)lParam;
tmessage((PUniMessage)myPcd->lpData);
break;
}
case WM_PAINT:
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}