自己项目中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);

 


// 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);
        
forint 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);
            forint 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;
}


 

 

posted @ 2008-11-23 19:22  烤狐  阅读(3872)  评论(2编辑  收藏  举报