键盘自学,Windows程序设计零基础自学_6_键盘_之键盘消息_实例代码

好久没有学习Windows下的编程了, 因为我发现在学习Delphi时;看书的时候一会儿就涉及到windows编程的机制了。
因此在今天有时间的时候学习一下windows的编程。
Windows程序设计零基础自学_6_键盘_之键盘消息_实例代码键盘自学Windows程序设计零基础自学_6_键盘_之键盘消息_实例代码键盘自学View Code #include //#include "sysmets.h" LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int iShowCmd) { static TCHAR szAppName[]=TEXT("SysMets4"); static TCHAR szNeedNT[]=TEXT("You need winNT to run this program!"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.cbClsExtra=0; wndclass.cbWndExtra=0; wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); wndclass.hInstance=hInstance; wndclass.lpfnWndProc=WndProc; wndclass.lpszClassName=szAppName; wndclass.lpszMenuName=NULL; wndclass.style=CS_VREDRAW | CS_HREDRAW; if(!RegisterClass(&wndclass)) { MessageBox(NULL,szNeedNT,"Warning",MB_OK); return 0; } hwnd=CreateWindow(wndclass.lpszClassName, szAppName, WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd,iShowCmd); 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; static int cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth; int i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd; SCROLLINFO si; //通过这个结构体来处理与滚动条相关的消息 /* 结构体的SCROLLINFO typedef struct tagSCROLLINFO { UINT cbSize; //这个字段表示的是结构体变量的大小, 通常设定为cbsize=sizeof SCROLLINFO; UINT fMask; //调用GetScrollInfo函数和SetScrollPosInfo函数时想要设定的值 int nMin; //V_Range或者R_Range的最小值 int nMax; //滚动范围的最大值 UINT nPage; // 页面的大小, 这个值一般是cyClient/cyChar的大小 int nPos; // 滚动条的当前位置 int nTrackPos; // } SCROLLINFO, FAR *LPSCROLLINFO; fMask指定使用结构中哪些成员,不指定的就不使用;可以是以下几个值的任意组合 SIF_ALL SIF_DISABLENOSCROLL SIF_PAGE SIF_POS SIF_RANGE SIF_TRACKPOS 函数SetScrollInfo和GetScrollInfo的参数LPSCROLLINFO lpsi指向该结构。在程序中,可以定义如下的SCROLLINFO结构型态: SCROLLINFO si ; 在调用SetScrollInfo或GetScrollInfo之前,必须将cbSize字段设定为结构的大小: si.cbSize = sizeof (si) ; 或 si.cbSize = sizeof (SCROLLINFO) ; 把fMask字段设定为一个以上以SIF前缀开头的旗标,并且可以使用C的位操作OR运算子(|)组合这些旗标。 SetScrollInfo函数使用SIF_RANGE旗标时,必须把nMin和nMax字段设定为所需的卷动列范围。 GetScrollInfo函数使用SIF_RANGE旗标时,应把nMin和nMax字段设定为从函数传回的目前范围。 SIF_POS旗标也一样。当通过SetScrollInfo使用它时,必须把结构的nPos字段设定为所需的位置。 可以通过GetScrollInfo使用SIF_POS旗标来取得目前位置。 使用SIF_PAGE旗标能够取得页面大小。用SetScrollInfo函数把nPage设定为所需的页面大小。 GetScrollInfo使用SIF_PAGE旗标可以取得目前页面的大小。如果不想得到比例化的卷动列,就不要使用该旗标。 当处理带有SB_THUMBTRACK或SB_THUMBPOSITION通知码的WM_VSCROLL或WM_HSCROLL消息时,通过GetScrollInfo只使用SIF_TRACKPOS旗标。 从函数的传回中,SCROLLINFO结构的nTrackPos字段将指出目前的32位的卷动方块位置。 */ //TCHAR szBuffer[10]; TEXTMETRIC tm; switch(message) { case WM_CREATE: hdc=GetDC(hwnd); /* tm结构体的定义: */ GetTextMetrics(hdc,&tm); //通过这个函数获取设备内容中关于字符系统信息 cxChar=tm.tmAveCharWidth; //表示字符的平均宽度 cyChar=tm.tmHeight+tm.tmExternalLeading; //字符的高度 cxCaps=(tm.tmPitchAndFamily & 1 ? 3:2)*cxChar /2; ReleaseDC(hwnd,hdc); iMaxWidth=40 * cxChar + 22 * cxCaps; return 0; case WM_SIZE: /* WM_SIZE消息: The WM_SIZE message is sent to a window after its size has changed. 当窗口大小发生变化时发送给窗口的消息。 当窗口处理函数接收到WM_SIZE消息时, message会接收一个wm_size消息,而消息的附加消息 会保存在wParam中,其中wParam分为两段: 低字: 保存窗口大小改变后x方向客户区的大小 高字: 保存窗口大小改变后y方向客户区的大小 */ cxClient=LOWORD(lParam); cyClient=HIWORD(lParam); si.cbSize=sizeof si; //在函数中使用滚动条的滚动范围信息和页面大小信息,这个地方还需要进一步理解 si.fMask=SIF_RANGE | SIF_PAGE; si.nMin = 0; si.nMax = 100-1; si.nPage = cyClient/cyChar; SetScrollInfo(hwnd,SB_VERT,&si,TRUE); //SB_VERT:用于窗口中标准垂直滚动条,此处函数仅改变垂直方向的信息 si.cbSize=sizeof si; si.fMask=SIF_RANGE | SIF_PAGE; si.nMin = 0; si.nMax=2+iMaxWidth+cyChar; si.nPage=cxClient/cxChar; SetScrollInfo(hwnd,SB_HORZ,&si,TRUE); //SB_HORZ:用于窗口中水平滚动条,此处函数仅改变水平方向滚动条的信息 return 0; case WM_VSCROLL: /* WM_VSCROLL:窗口的垂直滚动条消息。 当接收到这个消息时,wParam参数会附加消息码/通知码。 wParam附加通知码存在该参数的低字, 可以通过LOWORD获取这个通知码消息,并且在一个switch中进行 进行处理。 */ si.cbSize=sizeof(si); si.fMask=SIF_ALL; GetScrollInfo(hwnd,SB_VERT,&si); iVertPos=si.nPos; switch(LOWORD(wParam)) { case SB_TOP: si.nPos=si.nMin; break; case SB_BOTTOM: si.nPos=si.nMax; break; case SB_LINEUP: si.nPos += -1; break; case SB_LINEDOWN: si.nPos += 1; break; case SB_PAGEUP: si.nPos -=si.nPage; break; case SB_PAGEDOWN: si.nPos=si.nPos+si.nPage; break; case SB_THUMBTRACK: si.nPos=si.nTrackPos; break; default: break; } //Scroll 附加消息处理 si.fMask=SIF_POS; SetScrollInfo(hwnd,SB_VERT,&si,TRUE); GetScrollInfo(hwnd,SB_VERT,&si); if(si.nPos!=iVertPos) { ScrollWindow(hwnd,0,cyChar*(iVertPos-si.nPos),NULL,NULL); UpdateWindow(hwnd); } return 0; case WM_HSCROLL: /* WM_HSCROLL:窗口的水平滚动条消息。 当接收到这个消息时,wParam参数会附加消息码/通知码。 wParam附加通知码存在该参数的低字, 可以通过LOWORD获取这个通知码消息,并且在一个switch中进行 进行处理。 */ si.cbSize=sizeof(si); si.fMask=SIF_ALL; GetScrollInfo(hwnd,SB_HORZ,&si); iHorzPos=si.nPos; switch(LOWORD(wParam)) { case SB_LINELEFT: si.nPos += -1; break; case SB_LINERIGHT: si.nPos++; break; case SB_PAGELEFT: si.nPos -=si.nPage; break; case SB_PAGERIGHT: si.nPos +=si.nPos; break; case SB_THUMBPOSITION: si.nPos=si.nTrackPos; break; default: break; } // scroll 附加消息处理 si.fMask=SIF_POS; SetScrollInfo(hwnd,SB_HORZ,&si,TRUE); GetScrollInfo(hwnd,SB_HORZ,&si); if(si.nPos != iHorzPos) { ScrollWindow(hwnd,cxChar*(iHorzPos-si.nPos),0,NULL,NULL); } return 0; case WM_KEYDOWN: /* WM_KEYDOWN: 窗口的键盘消息 键盘消息分为: WM_KEYDOWN WM_KEYUP WM_SYSKEYDOWN WM_SYSKEYUP 这里处理的是非系统键按下消息。 因为键比较多,因此也需要一个消息的附加信息, 这个附加信息还是通过wParam参数进行传递 通常键盘消息的wParam附加信息,成为虚拟键码。 这个参数信息通常用VK_ 开头表示。 在键盘消息里面lParam参数也包含了丰富的信息,这些信息与lParam各个位的取值相关。 */ switch(wParam) { case VK_HOME: SendMessage(hwnd,WM_VSCROLL,SB_TOP,0); break; case VK_END: SendMessage(hwnd,WM_VSCROLL,SB_BOTTOM,0); break; case VK_PRIOR: SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,0); break; case VK_NEXT: SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,0); break; case VK_UP: SendMessage(hwnd,WM_VSCROLL,SB_LINEUP,0); break; case VK_DOWN: SendMessage(hwnd,WM_VSCROLL,SB_LINEDOWN,0); break; case VK_LEFT: SendMessage(hwnd,WM_HSCROLL,SB_LINELEFT,0); break; case VK_RIGHT: SendMessage(hwnd,WM_HSCROLL,SB_LINERIGHT,0); break; case VK_LWIN: MessageBox(hwnd,"You have press left win key!","提示",MB_OK); break; } //keydown 消息处理 case WM_PAINT: hdc=BeginPaint(hwnd,&ps); si.cbSize=sizeof(si); si.fMask=SIF_POS; GetScrollInfo(hwnd,SB_VERT,&si); iVertPos=si.nPos; GetScrollInfo(hwnd,SB_HORZ,&si); iHorzPos=si.nPos; iPaintBeg=max(0,iVertPos+ps.rcPaint.top/cyChar); iPaintEnd=min(1000-1,iVertPos+ps.rcPaint.bottom/cyChar); for(i=iPaintBeg;i<=iPaintEnd;i++) { x=cxChar* (1-iHorzPos); y=cxChar*(1-iVertPos); TextOut(hdc,x,y,"abc",strlen("abc")); TextOut(hdc,x+22*cxCaps,y,"abcdefg",strlen("abcdefg")); SetTextAlign(hdc,TA_RIGHT | TA_TOP); }//for 循环 EndPaint(hwnd,&ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,message,wParam,lParam); }
我发现在目前我学习过的windows编程知识里面,滚动条的处理和字符系统处理比较困难。
哈哈, 希望自己能够坚持下去, 在2009年的时候,就打算学习win的编程,结果没有坚持下去,
当时学习的东西又基本忘记了,
好在目前有博客园,在这里记录学习的点滴,促使我一直坚持学习............
Tags:  自学考试科目代码 轻松自学键盘 键盘自学

延伸阅读

最新评论

发表评论