26
2014
07

C++windows内核编程笔记day03_day04_day05

windows消息机制、消息格式和消息处理1


unicode支持,windows下用:

1、先在#include<windows.h>上面,定义 UNICODE

#define UNICODE

2、定义字符串

TCHAR * ptxt=TEXT("学习hello c++");

3、根据需要,打印不同格式字符串

#ifdef UNICODE

    wprintf(L"%s\n",ptxt);

#else

    printf("%s\n",ptxt);

#endif


打印UNICODE WriteConsole API函数:

HANDLE hstd=GetStdHandle(STD_OUTPUT_HANDLE);

wchar_t tc=300;

WriteConsole(hstd,&tc,1,NULL,NULL);



day66 am over

//winpro中,处理点击关闭时,返回0,退出消息循环(退出程序)

    switch(msg)

    {

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    }

//窗口类缓冲区大小,基于一个窗口类创建出来的所有窗口共享的缓冲区

wce.cbClsExtra=0;//数据是4的整数倍,一般200

//写入数据:

DWORD SetClassLong(  HWND hWnd,       // handle to window

  int nIndex,      // 字节索引

  LONG dwNewLong   // new value

  );

 //读取数据

 DWORD GetClassLong(  HWND hWnd,  // handle to window

  int nIndex  // 字节索引

  );

  //窗口缓冲区大小,某一个窗口的数据缓冲区

      wce.cbWndExtra=0;

    //写入数据

    LONG SetWindowLong(  HWND hWnd,       // handle to window

  int nIndex,      // 字节索引

  LONG dwNewLong   // new value

  );

  //获取数据

  LONG GetWindowLong(  HWND hWnd,  // handle to window

  int nIndex  //字节索引

  );

//系统消息格式

  typedef struct tagMSG {

  HWND   hwnd;

  UINT   message;

  WPARAM wParam;

  LPARAM lParam;

  DWORD  time;

  POINT  pt;

} MSG, *PMSG;


//在创建窗口之后还未显示的时候

    case WM_CREATE:

        OnCreate(hwnd,lparam);

void OnCreate(HWND hwnd,LPARAM lparam)

{

    CREATESTRUCT *pcs=(CREATESTRUCT*)lparam;

    //对应CreateWindowEx的12个参数

    char * txt=(char *)pcs->lpCreateParams;//最后的附加参数

    MessageBox(NULL,txt,"info",MB_OK);

}



day66 pm over

void OnSizeChange(HWND hwnd,LPARAM lparam)

{

    int w=LOWORD(lparam);

    int h=HIWORD(lparam);

    HWND he=GetDlgItem(hwnd,1001);

    MoveWindow(he,0,0,w,h);

}

//窗口大小变化时产生消息

    case WM_SIZE:

        OnSizeChange(hwnd,lparam)

        break;

//windows发送消息

SendMessage//发送消息,等待消息返回

PostMessage//发送消息,不等待消息返回

    PostMessage(hwnd,WM_QUIT,0,0);//发送退出消息

用户自定义消息定义(可用31743个),如下:

#define WM_MYMSG WM_USER+1

#define WM_MYMSG2 WM_USER+2


case WM_PAINT://窗口重新绘制

        OnPaint(hwnd);

        break;

case WM_LBUTTONDOWN://点击鼠标左键,

        InvalidateRect(hwnd,NULL,NULL);//窗口重绘

        break;

//窗口绘图

void OnPaint(HWND hwnd)

{

    WriteConsole(g_houtput,"wm_paint\n",9,NULL,NULL);

    PAINTSTRUCT ps={0};

    HDC hdc=BeginPaint(hwnd,&ps);//必须在WM_PAINT消息处理函数中使用

    TextOut(hdc,200,200,"hello",5);//绘制字符串到界面

    EndPaint(hwnd,&ps);

}


键盘消息:

    case WM_KEYDOWN://键盘按键消息

        OnKeydown(hwnd,wparam);

        break;

void OnKeydown(HWND hwnd,WPARAM wparam)

{

    char txt[200]={0};

    sprintf(txt,"wm_keydown:%08X,%d\n",wparam,wparam);//虚拟键码

    WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);

    switch(wparam)

    {

    case VK_UP:

        g_ypos-=10;

        if(g_ypos<0) g_ypos=0;

        break;

    case VK_DOWN:

        g_ypos+=10;

        break;

    case VK_LEFT:

        g_xpos-=10;

        if(g_xpos<0) g_xpos=0;

        break;

    case VK_RIGHT:

        g_xpos+=10;

        break;

    }

    InvalidateRect(hwnd,NULL,TRUE);//重新绘制窗口

}

case WM_CHAR://translateMessage发送的,只有可见字符才能触发

    on_char(hwnd,wparam,lparam);

void on_char(HWND hwnd,WPARAM wparam,LPARAM lparam)

{

    char txt[200]={0};

    sprintf(txt,"char code %08X,%d\n",wparam,wparam);//ascii码

    WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);

}


鼠标消息:函数参数大致相同,查看MSDN Library就知道了。

    case WM_LBUTTONDOWN://点击鼠标左键,

    case WM_LBUTTONUP:

    case WM_RBUTTONDOWN:

    case WM_RBUTTONUP:

    case WM_MOUSEMOVE:

    case WM_LBUTTONDBLCLK://在注册窗口风格中要加 CS_DBLCLKS

    case WM_RBUTTONDBLCLK:

    case WM_MOUSEWHEEL:

    case WM_MOUSELEAVE:


如:

    case WM_LBUTTONUP://点击鼠标左键,

        onLbuttondown(hwnd,wparam,lparam);

        break;

void onLbuttondown(HWND hwnd,WPARAM wparam,LPARAM lparam)

{

    char txt[200]={0};

    if(wparam&MK_LBUTTON==MK_LBUTTON) wparam=wparam-MK_LBUTTON;//排除本身

    if(wparam&MK_SHIFT==MK_SHIFT) {}//shift键按下

    if(wparam&MK_RBUTTON==MK_RBUTTON) {}//右键按下

    sprintf(txt,"其他键:%08X,x=%d,y=%d\n",wparam,LOWORD(lparam),HIWORD(lparam));//可见字符的ascii码

    WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);

}

        case WM_MOUSEMOVE://鼠标移动

            OnMouseMove(hwnd,lparam);

            break;

void OnMouseMove(HWND hwnd,LPARAM lparam)

{

    char txt[200]={0};

    sprintf(txt,"mouse move:x=%d,y=%d\n",LOWORD(lparam),HIWORD(lparam));//可见字符的ascii码

    WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);

}

//鼠标双击的触发顺序:单击down,单击up,双击down,单击up

//在.h文件中加定义指定系统最低版本:

#define _WIN32_WINNT 0X400


        case WM_MOUSEWHEEL://鼠标滚轮

            OnMouseWheel(hwnd,wparam);

            break;

void OnMouseWheel(HWND hwnd,WPARAM wparam){

    short npy=HIWORD(wparam);//滚轮移动的偏移量

    char txt[200]={0};

    sprintf(txt,"OnMouseWheel:x=%d\n",npy);

    WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);

}


定时器消息WM_TIMER://不太精确

UINT setTimer(HWND hwnd,UINT id)

{

    SetTimer(hwnd,id,1000,timer1);//可以在这里直接指定处理函数

    //SetTimer(hwnd,id,1000,NULL);//在WM_TIMER中捕捉再处理

    return id;

}

//直接指定的处理函数

void CALLBACK  timer1(HWND hwnd,UINT umsg,UINT uid,DWORD dwtime)

{

    char txt[200]={0};

    sprintf(txt,"timer1:id=%d\n",uid);

    WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);

}


day68 pm 96

//在WM_TIMER中捕捉再处理

    case WM_TIMER:

        timer1Proc(hwnd,msg,wparam,lparam);

        break;

LRESULT CALLBACK timer1Proc(

                            HWND hwnd,       // handle to window

                            UINT uMsg,       // WM_TIMER

                            WPARAM wParam,   // timer identifier

                            LPARAM lParam    // timer callback (TIMERPROC)

)

{

    char txt[200]={0};

    sprintf(txt,"timer1:id=%d\n",wParam);

    WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);

    return 0;

}

    RECT rc={0};

    GetClientRect(hwnd,&rc);//获取窗口边界

    //画圆

    RECT g_rc={0};

    PAINTSTRUCT ps={0};

    HDC hdc=BeginPaint(hwnd,&ps);//必须在WM_PAINT消息处理函数中使用

    //TextOut(hdc,g_xpos,g_ypos,"hello",5);//绘制字符串到界面

    Ellipse(hdc,g_rc.left,g_rc.top,g_rc.right,g_rc.bottom);

    EndPaint(hwnd,&ps);


代码示例:


和day01一样,建立程序 ,


修改stdafx.h ,  加一行: #define _WIN32_WINNT 0X400


修改主要cpp文件:

// win4.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <stdio.h>
HINSTANCE g_hinstance=0;//全局句柄
HANDLE g_houtput=0;
HWND g_edit=0;
int g_xpos=100;
int g_ypos=100;
#define WM_MYMSG WM_USER+1
UINT setTimer(HWND hwnd,UINT id)
{
SetTimer(hwnd,id,1000,NULL);//可以在这里指定处理函数,也可以在WM_TIMER中捕捉再处理
return id;
}
void SetExtra(HWND hwnd)
{
SetClassLong(hwnd,0,301);
SetWindowLong(hwnd,0,401);
}
void GetExtra(HWND hwnd)
{
long nc= GetClassLong(hwnd,0);
long nw=GetWindowLong(hwnd,0);
char txt[200]={0};
sprintf(txt,"%d,%d",nc,nw);
MessageBox(NULL,txt,"info",MB_OK);
}
void OnCreate(HWND hwnd,LPARAM lparam)
{
//g_edit=CreateWindowEx(0,"edit","hello",WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,
//200,200,hwnd,NULL,g_hinstance,NULL);
SendMessage(hwnd,WM_MYMSG,1,2);
setTimer(hwnd,1023);
//PostMessage(hwnd,WM_MYMSG,1,2);
}
void OnSizeChange(HWND hwnd,LPARAM lparam)
{
int width=LOWORD(lparam);
int height=HIWORD(lparam);
//改变窗口大小时,同时改编辑框大小
//MoveWindow(g_edit,0,0,width,height,TRUE);
CHAR txt[40]={0};
sprintf(txt,"%d,%d\n",width,height);
WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);
}
//窗口绘图
void OnPaint(HWND hwnd)
{
WriteConsole(g_houtput,"wm_paint\n",9,NULL,NULL);
PAINTSTRUCT ps={0};
HDC hdc=BeginPaint(hwnd,&ps);//必须在WM_PAINT消息处理函数中使用
TextOut(hdc,g_xpos,g_ypos,"hello",5);//绘制字符串到界面
EndPaint(hwnd,&ps);
}
void OnKeydown(HWND hwnd,WPARAM wparam)
{
//WriteConsole(g_houtput,"wm_keydown\n",11,NULL,NULL);
bool ischange=false;
switch(wparam)
{
case VK_UP:
g_ypos-=10;
if(g_ypos<0) g_ypos=0;
ischange=true;
break;
case VK_DOWN:
g_ypos+=10;
ischange=true;
break;
case VK_LEFT:
g_xpos-=10;
if(g_xpos<0) g_xpos=0;
ischange=true;
break;
case VK_RIGHT:
g_xpos+=10;
ischange=true;
break;
}
if(ischange) InvalidateRect(hwnd,NULL,TRUE);
}
void OnKeyup(HWND hwnd,WPARAM wparam)
{
char txt[200]={0};
sprintf(txt,"VIRTUAL KEY:%08X,%d\n",wparam,wparam);//虚拟键码
WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);
}
void on_char(HWND hwnd,WPARAM wparam,LPARAM lparam)
{
char txt[200]={0};
sprintf(txt,"char code %08X,%d\n",wparam,wparam);//可见字符的ascii码
WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);
}
void onLbuttondown(HWND hwnd,WPARAM wparam,LPARAM lparam)
{
char txt[200]={0};
if(wparam&MK_LBUTTON==MK_LBUTTON) wparam=wparam-MK_LBUTTON;//排除本身
if(wparam&MK_SHIFT==MK_SHIFT) {}//shift键按下
if(wparam&MK_RBUTTON==MK_RBUTTON) {}//右键按下
sprintf(txt,"onLbuttondown:其他键:%08X,x=%d,y=%d\n",wparam,LOWORD(lparam),HIWORD(lparam));//可见字符的ascii码
WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);
}
void OnMouseMove(HWND hwnd,LPARAM lparam)
{
char txt[200]={0};
g_xpos=LOWORD(lparam);
g_ypos=HIWORD(lparam);
sprintf(txt,"mouse move:x=%d,y=%d\n",g_xpos,g_ypos);//可见字符的ascii码
WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);
InvalidateRect(hwnd,NULL,TRUE);
}
void OnLbuttonDBClk(HWND hwnd)
{
char txt[200]={0};
sprintf(txt,"OnLbuttonDBClk\n");
WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);
}
void OnMouseWheel(HWND hwnd,WPARAM wparam){
short npy=HIWORD(wparam);//滚轮移动的偏移量
char txt[200]={0};
sprintf(txt,"OnMouseWheel:x=%d\n",npy);
WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);
}
void CALLBACK  timer1(HWND hwnd,UINT umsg,UINT uid,DWORD dwtime)
{
char txt[200]={0};
sprintf(txt,"timer1:id=%d\n",uid);
WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);
}
LRESULT CALLBACK timer1Proc(
HWND hwnd,       // handle to window
UINT uMsg,       // WM_TIMER
WPARAM wParam,   // timer identifier
LPARAM lParam    // timer callback (TIMERPROC)
)
{
char txt[200]={0};
sprintf(txt,"timer1:id=%d\n",wParam);
WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);
return 0;
}
//回调函数
LRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch(msg)
{
case WM_SYSCOMMAND:
if(wparam==SC_CLOSE){
int ret=MessageBox(NULL,"是否退出","info",MB_YESNO);
if(ret==IDYES){
//下面代码会自动关闭和销毁
//PostQuitMessage(0);
}
else return 0;//不执行下面代码
}
break;
//窗口大小变化时产生消息
case WM_SIZE:
OnSizeChange(hwnd,lparam);
break;
case WM_CREATE:
OnCreate(hwnd,lparam);
break;
case WM_DESTROY:
//PostQuitMessage(0);
PostMessage(hwnd,WM_QUIT,0,0);
break;
case WM_MYMSG://处理自定义消息
WriteConsole(g_houtput,"wm_mymsg\n",9,NULL,NULL);
break;
case WM_PAINT://窗口重新绘制
OnPaint(hwnd);
break;
case WM_LBUTTONDOWN://点击鼠标左键,
onLbuttondown(hwnd,wparam,lparam);
break;
case WM_LBUTTONUP://点击鼠标左键,
onLbuttondown(hwnd,wparam,lparam);
break;
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
break;
case WM_MOUSEMOVE:
//OnMouseMove(hwnd,lparam);
break;
case WM_MOUSEWHEEL://鼠标滚轮
OnMouseWheel(hwnd,wparam);
break;
case WM_LBUTTONDBLCLK://在注册窗口风格中要加 CS_DBLCLKS
OnLbuttonDBClk(hwnd);
break;
case WM_RBUTTONDBLCLK:
//InvalidateRect(hwnd,NULL,NULL);//窗口重绘
break;
case WM_KEYDOWN://键盘按键消息
OnKeydown(hwnd,wparam);
break;
case WM_KEYUP://键盘按键消息
OnKeyup(hwnd,wparam);
break;
case WM_TIMER:
timer1Proc(hwnd,msg,wparam,lparam);
break;
case WM_CHAR://translateMessage发送的,只有可见字符才能触发
//on_char(hwnd,wparam,lparam);
break;;
}
return DefWindowProc(hwnd,msg,wparam,lparam);
}
//注册窗口类
BOOL Register(LPSTR lpClassName,WNDPROC wndproc)
{
WNDCLASSEX wce={0};
wce.cbSize=sizeof(wce);
wce.cbClsExtra=200;
wce.cbWndExtra=200;
wce.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wce.hCursor=NULL;
wce.hIcon=NULL;
wce.hIconSm=NULL;
wce.hInstance=g_hinstance;
wce.lpfnWndProc=wndproc;
wce.lpszClassName=lpClassName;
wce.lpszMenuName=NULL;
wce.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
ATOM atom= RegisterClassEx(&wce);
if(atom==0){
MessageBox(NULL,"注册失败","info",MB_OK);
return FALSE;
}
return TRUE;
}
//创建窗口
HWND CreateMain(LPSTR lpClassName,LPSTR lpWndName)
{
HWND hwnd=CreateWindowEx(0,lpClassName,lpWndName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,g_hinstance,"hello create");
return hwnd;
}
//创建子窗口
HWND CreateChild(HWND phwnd,LPSTR lpClassName,LPSTR lpWndName)
{
if(Register(lpClassName,DefWindowProc)==0)
{
MessageBox(phwnd,"创建子窗口失败","info",MB_OK);
return NULL;
}
//子窗口风格,都要 WS_CHILD|WS_VISIBLE
HWND hwnd=CreateWindowEx(0,lpClassName,lpWndName,WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
200,200,phwnd,NULL,g_hinstance,NULL);
return hwnd;
}
//显示窗口
void Display(HWND hwnd)
{
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
}
//处理消息
void MSGdeal()
{
 MSG msg={0};
while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);//翻译消息 
DispatchMessage(&msg);//派发给 WinProc 处理消息 
}
// while(1)
// {
// if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))//有消息
// {
// if(!GetMessage(&msg,NULL,0,0)) return;
// else
// {
// TranslateMessage(&msg);//翻译消息,只翻译可见字符
// DispatchMessage(&msg);//派发给 WinProc 处理消息 
// }
// }
// else//无消息
// {
// //WriteConsole(g_houtput,"nomsg\n",6,NULL,NULL);
// //Sleep(1);
// }
// }
}
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
AllocConsole();//调试程序方法
g_houtput=GetStdHandle(STD_OUTPUT_HANDLE);
g_hinstance=hInstance;
 // TODO: Place code here.
//SysReg();
//AppReg();
if(Register("main",WinProc)==0)
{
MessageBox(NULL,"注册失败","提示",MB_OK);
return 0;
}
HWND hwnd= CreateMain("main","pro1");
Display(hwnd);
// HWND hchild=CreateChild(hwnd,"child1","child1");//创建子窗口
// HWND hchild2=CreateChild(hwnd,"child2","child2");
// 
// MoveWindow(hchild,300,200,200,200,TRUE);
// MoveWindow(hchild2,500,200,200,200,TRUE);
// SetExtra(hchild);
// GetExtra(hchild2);
MSGdeal();
return 0;
}




版权声明:
作者:真爱无限 出处:http://www.pukuimin.top 本文为博主原创文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接.
« 上一篇下一篇 »

相关文章:

评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。