例如下面的代码,在进入消息循环之前要初始化一些数据。如果初始化失败,则不经过消息循环直接销毁窗口、清理已初始化的部分,然后返回操作系统。
不过DestroyWindow()函数自身会发送消息,我没经过主消息循环,那些消息自然无法处理了。这会不会影响主窗口的销毁?[code] ...
// 程序初始化,如果失败则关闭主窗口
if (Init() != 1)
{
DestroyWindow(main_window_handle);
Shutdown(); // 程序退出前的清理工作
return false;
} // 主消息循环
while(TRUE)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} // end while // 程序退出前的清理工作
Shutdown();
return (int)msg.wParam;
}
[/code]

解决方案 »

  1.   

    ...
    // 程序初始化,如果失败则关闭主窗口
    if (Init() != 1)
    {
    DestroyWindow(main_window_handle);
    Shutdown(); // 程序退出前的清理工作
    return false;
    } // 主消息循环
    while(TRUE)
    {
    if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

    if (msg.message == WM_QUIT)
    break;
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    } // end while // 程序退出前的清理工作
    Shutdown();
    return (int)msg.wParam;
    }
      

  2.   

    我觉得你可以避免这样做,你可以将窗口的创建工作放在后面,先进行数据初始化不就行了,这样就不会出现你所说的问题了,至于你所问的,我觉得在消息循环还没有建立之前用DestroyWindow是有问题的,因为这个API主要是通过发送WM_DESTROY和WM_NCDESTROY来达到目的,真正关闭窗口的工作是DefWindowProc,这要通过消息循环才能传给它
      

  3.   

    这个初始化工作必须等到窗口建立后才能进行,因为要获取窗口的某些数据。
    如果不能用DestroyWindow()的话,该用什么方法安全关闭窗口呢?
      

  4.   

    获取窗口的数据?
    为什么不在 OnCreate内做 ?或是 在Oninit 之类的地方获取
    这样 获取数据之后就直接在函数初始化,失败直接Destory 这样也不会影响消息循环
      

  5.   

    获得WM_CREATE消息时窗口还在创建,无法获得窗口在屏幕上的位置。
    以下代码无法在WM_CREATE消息中成功使用,但在窗口创建后、进入消息循环前可以。 // 计算用户区左上角在屏幕上的位置
    POINT client_point = {0,0}; // 用户区左上角相对于自己的坐标
    ClientToScreen(main_window_handle, &client_point);
      

  6.   

    > 在消息循环之前,窗口根本就不可能完全创建好.我原来也是这么以为的,但因为上面的代码,我就不这么以为了。反而在WM_CREATE消息中,我怀疑窗口还没创建好。
      

  7.   

    队列消息和非队列消息  从消息的发送途径来看,消息可以分成2种:队列消息和非队列消息。消息队列由可以分成系统消息队列和线程消息队列。系统消息队列由Windows维护,线程消息队列则由每个GUI线程自己进行维护,为避免给non-GUI现成创建消息队列,所有线程产生时并没有消息队列,仅当线程第一次调用GDI函数数系统给线程创建一个消息队列。队列消息送到系统消息队列,然后到线程消息队列;非队列消息直接送给目的窗口过程。  对于队列消息,最常见的是鼠标和键盘触发的消息,例如WM_MOUSERMOVE,WM_CHAR等消息,还有一些其它的消息,例如:WM_PAINT、WM_TIMER和WM_QUIT。当鼠标、键盘事件被触发后,相应的鼠标或键盘驱动程序就会把这些事件转换成相应的消息,然后输送到系统消息队列,由Windows系统去进行处理。Windows系统则在适当的时机,从系统消息队列中取出一个消息,根据前面我们所说的MSG消息结构确定消息是要被送往那个窗口,然后把取出的消息送往创建窗口的线程的相应队列,下面的事情就该由线程消息队列操心了,Windows开始忙自己的事情去了。线程看到自己的消息队列中有消息,就从队列中取出来,通过操作系统发送到合适的窗口过程去处理。  一般来讲,系统总是将消息Post在消息队列的末尾。这样保证窗口以先进先出的顺序接受消息。然而,WM_PAINT是一个例外,同一个窗口的多个 WM_PAINT被合并成一个 WM_PAINT 消息, 合并所有的无效区域到一个无效区域。合并WM_PAIN的目的是为了减少刷新窗口的次数。  非队列消息将会绕过系统队列和消息队列,直接将消息发送到窗口过程。例如,当用户激活一个窗口系统发送WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR。这些消息通知窗口它被激活了。非队列消息也可以由当应用程序调用系统函数产生。例如,当程序调用SetWindowPos系统发送WM_WINDOWPOSCHANGED消息。
      

  8.   

    > cnzdgs 能详细说说吗?为什么这样做是安全的?
      

  9.   

    那不就是说连DestroyWindow()都可以省了?
      

  10.   

    你要是直接退出进程的话,连ShotDown也可以省了。