标题:Windows API 关于模态对话框与非模态对话框的两个疑问?
只看楼主
yss28
Rank: 2
等 级:论坛游民
帖 子:16
专家分:76
注 册:2013-3-16
结帖率:66.67%
 问题点数:0 回复次数:3 
Windows API 关于模态对话框与非模态对话框的两个疑问?
程序代码:
#include <windows.h> 
#include "resource.h"

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

HWND hDlgModeless;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                   PSTR szCmdLine, int iCmdShow) 
{ 
    LPCWSTR szAppName = TEXT("Russian_Box");
    MSG msg; 
    HWND hwnd; 
    WNDCLASS wndclass; 

    wndclass.style= CS_HREDRAW | CS_VREDRAW; 
    wndclass.lpfnWndProc= WndProc; 
    wndclass.cbClsExtra= 0 ; 
    wndclass.cbWndExtra= 0 ; 
    wndclass.hInstance= hInstance; 
    wndclass.hIcon= LoadIcon(hInstance, szAppName) ; 
    wndclass.hCursor= LoadCursor(NULL, IDC_ARROW) ; 
    wndclass.hbrBackground= (HBRUSH) GetStockObject(WHITE_BRUSH) ; 
    wndclass.lpszMenuName= szAppName; 
    wndclass.lpszClassName= szAppName; 
    if (!RegisterClass(&wndclass)) 
    { 
        MessageBox( NULL, TEXT("This program requires Windows NT!"), 
            szAppName, MB_ICONERROR) ; 
        return 0 ; 
    } 

    hwnd= CreateWindow(szAppName, TEXT("RUSSIAN_BOX"), 
        WS_OVERLAPPEDWINDOW &  ~WS_SIZEBOX & ~WS_MAXIMIZEBOX, 
        CW_USEDEFAULT, CW_USEDEFAULT, 
        CW_USEDEFAULT, CW_USEDEFAULT, 
        NULL, NULL, hInstance, szCmdLine) ; 

    ShowWindow(hwnd, iCmdShow) ; 
    UpdateWindow(hwnd) ; 

    hDlgModeless= CreateDialog(hInstance, TEXT("Russian_Box"), hwnd, BoxDlgProc) ;

    while (GetMessage(&msg, NULL, 0, 0)) 
    { 
        if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))
        {
            TranslateMessage(&msg) ; 
            DispatchMessage(&msg) ;  
        }
    } 
    return msg.wParam; 
} 

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) 
{ 
    switch (message) 
    { 
        case WM_SETFOCUS:
            SetFocus (hDlgModeless);
            return 0;
        case WM_DESTROY: 
            DestroyWindow(hDlgModeless);
            PostQuitMessage(0) ; 
            return 0 ;
    } 
    return DefWindowProc(hwnd, message, wParam, lParam) ; 
} 

BOOL CALLBACK BoxDlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    {
    case WM_SETFOCUS:
        return TRUE;
    case WM_KILLFOCUS:
        SetFocus (hDlg);
        return TRUE;
    case WM_KEYDOWN:
        return TRUE;
    case WM_CHAR:
        return TRUE;
    } 
    return FALSE; 
} 


问题1:这个非模态对话框不能对 VK_LEFT、VK_UP、VK_DOWN....等几个键盘按键产生WM_KEYDOWN消息,应该是 IsDialogMessage() 导致的,那么问题来了,
我怎么样才能在按下键盘 方向键 的时候,使对话框处理程序收到 WM_KEYDOWN 消息????

问题2:我们知道TranslateMessage ()处理 WM_KEYDOWN 产生相应的 WM_CHAR 消息,从而在 WM_CHAR 消息中可以得到按下的是哪一个键,但是非模态对话框
的消息传递 通过 IsDialogMesage () , 并不经过 TranslateMessage() 处理,经实践,非模态对话框消息处理程序也不处理 WM_CHAR 消息(应该是收不到
这个消息),那么问题又来了, 非模态对话框怎么才能收到 WM_CHAR 消息????

问题3:这个是对模态对话框的困惑,创建模态对话框资源时,若加上 WS_CHILD 类型, 程序就卡死,我想问模态对话框是不是不可以带 WS_CHILD 类型???

(全是API调用的疑问, 不涉及MFC, 请尽量用 API 解答,谢谢各位大神了, 本人分不多,这点要sorry了)
搜索更多相关主题的帖子: 对话框 Windows 
2015-04-07 14:47
天使梦魔
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
得分:0 
不太清楚,也不太熟悉他们。
网上看到这样一句:CreateDialog函数调用了CreateWindowEx函数来创建窗口并立 即返回,之后这个窗口使用主窗口的消息循环(即这个窗口产生的消息可能直接发给这个窗口的处理函数,也可能进入主窗口的消息循环)

另外函数参数好像也不是bool,你确定这样传没问题?回叫函数的返回值万一是内部句柄要用呢?
查查msdn吧,假如同上面我复制的所说,共用一个消息泵,你所谓的部分能获取也许来自CreateWindow呢,来自主窗口的组合键。
原始api做东西不好弄啊,新版本vs和其它编译器都在升级api,好多已经废弃,好多已经变种。
2015-04-08 15:32
yss28
Rank: 2
等 级:论坛游民
帖 子:16
专家分:76
注 册:2013-3-16
得分:0 
回复 2楼 天使梦魔
谢谢回复,是不好弄,但我要弄个俄罗斯方块出来,完成一半的代码了,哎,摸索着来。

hDlgProc = (WNDPROC) SetWindowLong (hDlg, GWL_WNDPROC, (LONG)NewDlgProc);

LRESULT CALLBACK NewDlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_GETDLGCODE:
        return (DLGC_WANTALLKEYS | CallWindowProc(hDlgProc, hDlg, message, wParam, lParam));
    }
    return CallWindowProc (hDlgProc, hDlg, message, wParam, lParam);
}
对对话框窗口“子类化”(网上的词), 可以解决 VK_UP、VK_DOWN、、等在WM_KEYDOWN中的响应问题

至于怎么让对话框响应WM_CHAR,我就找不到方法了
2015-04-12 18:40
yss28
Rank: 2
等 级:论坛游民
帖 子:16
专家分:76
注 册:2013-3-16
得分:0 
以下是引用天使梦魔在2015-4-8 15:32:37的发言:

不太清楚,也不太熟悉他们。
网上看到这样一句:CreateDialog函数调用了CreateWindowEx函数来创建窗口并立 即返回,之后这个窗口使用主窗口的消息循环(即这个窗口产生的消息可能直接发给这个窗口的处理函数,也可能进入主窗口的消息循环)

另外函数参数好像也不是bool,你确定这样传没问题?回叫函数的返回值万一是内部句柄要用呢?
查查msdn吧,假如同上面我复制的所说,共用一个消息泵,你所谓的部分能获取也许来自CreateWindow呢,来自主窗口的组合键。
原始api做东西不好弄啊,新版本vs和其它编译器都在升级api,好多已经废弃,好多已经变种。


这种处理非模态对话框的消息处理方式是借鉴那本神书:windows程序设计,应该不会有问题吧,实际程序运行也没问题
2015-04-12 18:49



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-443649-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.281358 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved