鱼C论坛

 找回密码
 立即注册
查看: 2771|回复: 16

调用窗口过程的问题

[复制链接]
发表于 2013-10-15 17:16:10 | 显示全部楼层 |阅读模式
1鱼币
正常代码如下:
 /*------------------------------------------------------------
   HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
                 (c) Charles Petzold, 1998
  ------------------------------------------------------------*/
#include <windows.h>
 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("HelloWin") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     hwnd = CreateWindow (szAppName,                  // window class name
                          TEXT ("The Hello Program"), // window caption
                          WS_OVERLAPPEDWINDOW,        // window style
                          CW_USEDEFAULT,              // initial x position
                          CW_USEDEFAULT,              // initial y position
                          CW_USEDEFAULT,              // initial x size
                          CW_USEDEFAULT,              // initial y size
                          NULL,                       // parent window handle
                          NULL,                       // window menu handle
                          hInstance,                  // program instance handle
                          NULL) ;                     // creation parameters
     
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT        rect ;
     
     switch (message)
     {
     case WM_CREATE:
          PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
          return 0 ;
          
     case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;
          
          GetClientRect (hwnd, &rect) ;
          
          DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
          
          EndPaint (hwnd, &ps) ;
          return 0 ;
          
     case WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}
现在我把代码改了一下,窗口过程我直接调用,不用DispatchMessage (&msg) ;
就是把消息循环的部分改成下面那样
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
WndProc (hwnd,msg.message ,msg.wParam,msg.lParam);
}
请问这样会出现什么问题,为什么会出现问题呢,我试了下,反正窗口过程也能收到一些消息,但是处理过程好像总不对
求解答案

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-10-15 18:26:27 | 显示全部楼层
01.while(GetMessage(&msg,NULL,0,0))
仅仅能抓到“进队”消息,但兵不是所有的消息都是进队消息,一些“不进队”消息是由windows操作系统直接调用窗口过程的。这些消息你都接收不到了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 18:29:35 | 显示全部楼层

消息循环里处理的本来就是进队列的消息吧,不进队列的消息,也要通过DispatchMessage (&msg)发送吗,如果不用,是不是就一样了啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 18:30:56 | 显示全部楼层
仰望天上的光 发表于 2013-10-15 18:26
01.while(GetMessage(&msg,NULL,0,0))
仅仅能抓到“进队”消息,但兵不是所有的消息都是进队消息,一些“不 ...

好像有点明白,又好像没明白
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 18:32:37 | 显示全部楼层
仰望天上的光 发表于 2013-10-15 18:26
01.while(GetMessage(&msg,NULL,0,0))
仅仅能抓到“进队”消息,但兵不是所有的消息都是进队消息,一些“不 ...

对了,不进队列的消息,windows直接调用了,那是不是说连消息循环也不需要了,就是指不进队列的消息,窗口过程能收到吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-10-15 20:19:17 | 显示全部楼层
付笑 发表于 2013-10-15 18:29
消息循环里处理的本来就是进队列的消息吧,不进队列的消息,也要通过DispatchMessage (&msg)发送吗,如果 ...

不好意思,之前解释错了。其实DispatchMessage()基本上也就是做了一些工作后再调用窗口过程。所以,我个人觉得,你在这里直接调用窗口过程基本上也是可以的,但需要像DispatchMessage一样做一些琐碎的工作才能保证程序在任何情况下都正确。为了简化工作,让我们不需要知道太多操作系统底层的事情,。。。于是有了DispatchMessage这样的函数。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 20:55:08 | 显示全部楼层
仰望天上的光 发表于 2013-10-15 20:19
不好意思,之前解释错了。其实DispatchMessage()基本上也就是做了一些工作后再调用窗口过程。所以,我个人 ...

是这样啊,明白了,直接调用好像是有点问题,就是不知道问题是怎么回事,就是好像重给消息过来的时候,不播放声音了,但是重绘消息也确实来了,调试的时候发现有这个问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 20:57:32 | 显示全部楼层
仰望天上的光 发表于 2013-10-15 20:19
不好意思,之前解释错了。其实DispatchMessage()基本上也就是做了一些工作后再调用窗口过程。所以,我个人 ...

当然要把播放声音的语句放到重绘消息处理里面才调试的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 21:00:56 | 显示全部楼层
仰望天上的光 发表于 2013-10-15 20:19
不好意思,之前解释错了。其实DispatchMessage()基本上也就是做了一些工作后再调用窗口过程。所以,我个人 ...

我又试了下,好像那问题又没有了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 21:03:59 | 显示全部楼层
仰望天上的光 发表于 2013-10-15 20:19
不好意思,之前解释错了。其实DispatchMessage()基本上也就是做了一些工作后再调用窗口过程。所以,我个人 ...

用这段代码就有问题:

#include<windows.h>
#include<stdlib.h>
LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain
       (
       IN HINSTANCE hInstance,
       HINSTANCE hPrevInstance,
       PSTR szCmdLine,      //LPCTSTR多字节与宽字节通用的类型,PSTR为char类型
       int iCmdShow
       )
{
   static TCHAR szAppName[]=TEXT("hello windows");
   HWND      hwnd,hwnd2;  //窗口句柄
   MSG       msg;   //消息结构
   WNDCLASS  wndclass;  //窗口类结构
   char      s[100];
   int       Er;
   wndclass.style                =CS_HREDRAW|CS_VREDRAW;  //窗口类的风格,准确的说叫属性
   wndclass.lpfnWndProc          =WndProc;     //窗口过程指针
   wndclass.cbClsExtra    =0;
   wndclass.cbWndExtra           =0;
   wndclass.hInstance            =hInstance;//实例句柄,由主函数传入的参数
   wndclass.hIcon                =LoadIcon(NULL,IDI_QUESTION);//图标
   wndclass.hCursor              =LoadCursor(NULL,IDC_ARROW );
   wndclass.hbrBackground        =(HBRUSH) GetStockObject(BLACK_BRUSH);
   wndclass.lpszMenuName         =NULL;
   wndclass.lpszClassName        =szAppName;//窗口类名
   if(!RegisterClass(&wndclass))
   {
   
    Er=GetLastError();
    wsprintf(s,"窗口注册没有成功,错误代码:%d",Er);
    //MessageBox(NULL,TEXT("窗口注册没有成功"),szAppName,0);
    MessageBox(NULL,s,szAppName,0);
    return 0;
   
   }
     
    Er=GetLastError();
    wsprintf(s,"RegisterClass,错误代码:%d",Er);
    //MessageBox(NULL,TEXT("窗口注册没有成功"),szAppName,0);
    MessageBox(NULL,s,szAppName,0);

   hwnd=CreateWindow(
      szAppName,//窗口类名
      TEXT("The Hello Program 哈哈哈"), //窗口标题
      WS_OVERLAPPEDWINDOW,      //窗口风格
      CW_USEDEFAULT,            //初始坐标x
      CW_USEDEFAULT,            //初始坐标y
      CW_USEDEFAULT,            //初始大小x
      CW_USEDEFAULT,            //初始大小y
      NULL,
      NULL,
      hInstance,
      NULL

     );
   Er=GetLastError();
    wsprintf(s,"CreateWindow,错误代码:%d",Er);
    //MessageBox(NULL,TEXT("窗口注册没有成功"),szAppName,0);
    MessageBox(NULL,s,szAppName,0);
   hwnd2=CreateWindow(
      TEXT("Static"),//窗口类名
      TEXT("哈哈,这是按钮"), //窗口标题
      WS_CHILD|WS_BORDER  ,      //窗口风格
      100,            //初始坐标x
      100,            //初始坐标y
      300,            //初始大小x
      100,            //初始大小y
      hwnd,
      NULL,
      hInstance,
      NULL

     );
   ShowWindow(hwnd,iCmdShow);
   UpdateWindow(hwnd);
   ShowWindow(hwnd2,iCmdShow);
   UpdateWindow(hwnd2);
   //MessageBox(NULL,TEXT("hello,windows 98!"),TEXT("HelloMsg"),0);
  while(GetMessage(&msg,NULL,0,0))
   {
    TranslateMessage(&msg);
    //DispatchMessage(&msg);
    WndProc (hwnd,msg.message ,msg.wParam,msg.lParam);
   }
   //Sleep(5000);




return msg.wParam;
}
LRESULT CALLBACK WndProc (HWND hwnd,UINT message ,WPARAM wParam,LPARAM lParam)//此函数由操作系统调用,根据消息不同实现不现功能
{

char s[100];
HDC    hdc;    //设备环境句柄
PAINTSTRUCT  ps;    //绘图结构
RECT   rect;  //矩形结构


switch(message)
{
  case WM_DESTROY:
   {
    wsprintf(s,"%p",hwnd);
    MessageBox(NULL, s,TEXT("弹窗提示"),0);
    PostQuitMessage (0) ;
         
    return 0;
   }
  case WM_CREATE:
   {
    PlaySound(TEXT("HelloWin.wav"),NULL,SND_FILENAME|SND_ASYNC);
    return 0;
   }
  case WM_PAINT:
   {
     //Sleep(2000);
    PlaySound(TEXT("HelloWin.wav"),NULL,SND_FILENAME|SND_ASYNC);
    wsprintf(s,"%p 消息:%d",hwnd,message);
    //MessageBox(NULL, s,TEXT("弹窗提示"),0);
    hdc=BeginPaint(hwnd,&ps);
    GetClientRect(hwnd,&rect);
   
    //PlaySound(TEXT("HelloWin.wav"),NULL,SND_FILENAME|SND_ASYNC);
    DrawText(hdc,TEXT("哈哈哈!66666666666666666666"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
    EndPaint(hwnd,&ps);
    return 0;
   }
}





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


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 21:05:24 | 显示全部楼层
仰望天上的光 发表于 2013-10-15 20:19
不好意思,之前解释错了。其实DispatchMessage()基本上也就是做了一些工作后再调用窗口过程。所以,我个人 ...

这段代码就看不出区别了
/*------------------------------------------------------------
   HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
                 (c) Charles Petzold, 1998
  ------------------------------------------------------------*/

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("HelloWin") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     hwnd = CreateWindow (szAppName,                  // window class name
                          TEXT ("The Hello Program"), // window caption
                          WS_OVERLAPPEDWINDOW,        // window style
                          CW_USEDEFAULT,              // initial x position
                          CW_USEDEFAULT,              // initial y position
                          CW_USEDEFAULT,              // initial x size
                          CW_USEDEFAULT,              // initial y size
                          NULL,                       // parent window handle
                          NULL,                       // window menu handle
                          hInstance,                  // program instance handle
                          NULL) ;                     // creation parameters
     
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
         // DispatchMessage (&msg) ;
    WndProc (hwnd,msg.message ,msg.wParam,msg.lParam);
     }
     return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT        rect ;
     
     switch (message)
     {
     case WM_CREATE:
          PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
          return 0 ;
         
     case WM_PAINT:
    PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
          hdc = BeginPaint (hwnd, &ps) ;
         
          GetClientRect (hwnd, &rect) ;
         
          DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
         
          EndPaint (hwnd, &ps) ;
          return 0 ;
         
     case WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-10-15 22:30:23 | 显示全部楼层
付笑 发表于 2013-10-15 21:03
用这段代码就有问题:

#include

什么问题啊?我运行了没有问题。效果是一样的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 22:50:03 | 显示全部楼层
仰望天上的光 发表于 2013-10-15 22:30
什么问题啊?我运行了没有问题。效果是一样的。

改变窗口大小的时候,有问题那个不播放声音啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 22:54:57 | 显示全部楼层
仰望天上的光 发表于 2013-10-15 22:30
什么问题啊?我运行了没有问题。效果是一样的。

可能你是没有那个声音文件,所以看不出差别,"HelloWin.wav"
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-15 23:20:16 | 显示全部楼层
本帖最后由 付笑 于 2013-10-15 23:22 编辑
仰望天上的光 发表于 2013-10-15 22:30
什么问题啊?我运行了没有问题。效果是一样的。


有问题的代码用DispatchMessage (&msg)调用过程的时候,改变窗口大小,可以播放声音

用WndProc (hwnd,msg.message ,msg.wParam,msg.lParam);调用程,改变窗口大小就不能播放声音,就是有这个问题,没问题的代码,用哪一个都可以播放声音

声音文件 HelloWin.zip (26.77 KB, 下载次数: 1)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-10-16 08:35:56 | 显示全部楼层
付笑 发表于 2013-10-15 23:20
有问题的代码用DispatchMessage (&msg)调用过程的时候,改变窗口大小,可以播放声音

用WndProc (hwn ...

没有耳机哦。。。我之前都是把播放声音的注释掉了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-10-16 08:44:06 | 显示全部楼层
仰望天上的光 发表于 2013-10-16 08:35
没有耳机哦。。。我之前都是把播放声音的注释掉了。

嗨,那样就感觉是一样的了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 21:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表