您的位置:首页 > 其它

Windows程序内部运行机制

2006-06-01 14:32 232 查看
Windows程序设计是种事件驱动方式的程序设计,主要基于消息的。当用户需要完成某种功能时,需要调用OS某种支持,然后OS将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。

消息结构:
typedef struct tagMSG { // msg
HWND hwnd; //接收消息的窗口句柄。和哪个窗口相关联。
UINT message; //消息标识。消息本身是什么。
WPARAM wParam; //消息的附加信息。具体取决于消息本身。
LPARAM lParam;
DWORD time; //消息投递时间。
POINT pt; //消息投递时,光标在屏幕上的位置。
} MSG;

消息队列:
对于每个应用程序,OS都为它建立一个消息队列,消息队列是个先进先出的缓冲区,其中每个元素都是一个消息,OS将生成的每个消息按先后顺序放进消息队列中,应用程序总是取走当前消息队列中的第一条消息,应用程序取走消息后便知道用户的操作和程序的状态,然后对其处理即消息响应,消息响应通过编码实现。

使用VC编程除了良好的C基础外还需要掌握两方面:
(1)消息本身。不同消息所代表的用户操作和应用程序的状态。
(2)对于某个特定的消息来说,要让OS执行某个特定的功能去响应消息。

Window程序入口:
int WINAPI WinMain(
HINSTANCE hInstance, // 当前事例句柄。
HINSTANCE hPrevInstance, // 先前事例句柄。
LPSTR lpCmdLine, // 命令行指针
int nCmdShow // (窗口)显示的状态
);
说明:WinMain函数是Windows程序入口点函数,由OS调用,当OS启动应用程序的时候,winmain函数的参数由OS传递的。

创建一个完整的窗口需要经过下面四个操作步骤:
(1)设计一个窗口类;如:WNDCLASS wndcls;
(2)注册窗口类; 如:RegisterClass(&wndcls);
(3)创建窗口; 如:CreateWindow(),CreateWindowEX();
(4)显示及更新窗口;如:ShowWindow(),UpdateWindow();

Windows提供的窗口类:
typedef struct _WNDCLASS {
UINT style; //窗口的类型
WNDPROC lpfnWndProc; //窗口过程函数指针(回调函数)
int cbClsExtra; //窗口类附加字节,为该类窗口所共享。通常0。
int cbWndExtra; //窗口附加字节。通常设为0。
HANDLE hInstance; //当前应用程序事例句柄。
HICON hIcon; //图标句柄 LoadIcon();
HCURSOR hCursor; //光标句柄 LoadCursor();
HBRUSH hbrBackground; //画刷句柄 (HBRUSH)GetStockObject();
LPCTSTR lpszMenuName; //菜单名字
LPCTSTR lpszClassName; //类的名字
} WNDCLASS;

窗口类注册:
ATOM RegisterClass(
CONST WNDCLASS *lpWndClass // address of structure with class
// data
);

创建窗口:
HWND CreateWindow(
LPCTSTR lpClassName, // pointer to registered class name
LPCTSTR lpWindowName, // pointer to window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // handle to menu or child-window identifier
HANDLE hInstance, // handle to application instance
LPVOID lpParam // pointer to window-creation data
);

显示和更新窗口窗口:
BOOL ShowWindow(
HWND hWnd, // handle to window
int nCmdShow // show state of window
);
BOOL UpdateWindow(
HWND hWnd // handle of window
);

消息循环:
MSG msg;
while(GetMessage(&msg,...)) //从消息队列中取出一条消息
{
TranslateMessage(&msg); //进行消息(如键盘消息)转换
DispatchMessage(&msg); //分派消息到窗口的回调函数处理,(OS调用窗口回调函数进行处理)。
}
其中:
The GetMessage function retrieves a message from the calling thread's message queue and places it in the specified structure.
If the function retrieves a message other than WM_QUIT, the return value is nonzero.If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1.

窗口过程函数(回调函数)原型:
The WindowProc function is an application-defined function that processes messages sent to a window. The WNDPROC type defines a pointer to this callback function. WindowProc is a placeholder(占位符) for the application-defined function name.

   LRESULT CALLBACK WindowProc( //这里WindowProc是个代号名字。
    HWND hwnd, // handle to window
   UINT uMsg, // message identifier
   WPARAM wParam, // first message parameter
   LPARAM lParam // second message parameter
   );

   说明:两种函数调用约定(__stdcall 和 __cdecl):
   #define CALLBACK __stdcall
   //__stdcall 标准调用预定,是PASCAL 调用约定,象DELPHI使用的就是标准调用约定
   #define WINAPIV __cdecl
   // __cdecl 是C 语言形式的调用约定。

  主要区别:函数参数传递顺序 和 对堆栈的清除上。
  问题:除了那些可变参数的函数调用外,其余的一般都是__stdcall约定。但 C/C++编译默然的是__cdecl约  定。所以如果在VC等环境中调用__stdcall约定的函数,必须要在函数声明的时加上 __stdcall 修饰符,以便对这个函数的调用是使用__stdcall约定(如使用DELPHI编写的DLL时候)。
(VC中可通过这途径修改:project|settings..|c/c++|...)

  在窗口过程函数中通过一组switch语句来对消息进行处理:
  如:
  LRESULT CALLBACK WindowProc(
  HWND hwnd,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam
  )
  {
   switch(uMsg)
   {
      case WM_PAINT:
      ...
       break;
      case ...
       break;
      case WM_CLOSE:
       //DestroyWindow(hwnd);
            //销毁窗口,并发送WM_DESTROY消息。
       break;
      case WM_DESTROY:
       //PostQuitMessage(0);
             //发送WM_QUIT消息到消息队列中,请求终止。
      //GetMessage()取到WM_QUIT消息后,返回0,退出消息循 // 环,从而终止应用程序。
       break;
      default:
       return DefWindowProc(hwnd,uMsg,wParam,lParam);
            //用缺省的窗口过程处理我们不感兴趣的消息(其它消息)。
            //这是必须的。
    }//switch
  return 0;
  }//WindowProc

 13. DestroyWindow()函数和PostQuitMessage()函数原型:
//**The DestroyWindow function destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages。

  BOOL DestroyWindow(
  HWND hWnd // handle to window to destroy
  );

  VOID PostQuitMessage(
  int nExitCode // exit code
  );

 14. 关于DC句柄获取:
  a)使用BeginPaint(),EndPaint()对。注意只能在响应WM_PAINT消息时使用。
  b)使用GetDc(),ReleaseDC()对。注意他们不能在响应WM_PAINT中使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: