[Win32]键盘消息

1. 为Sysmets3程序添加击键消息:

    1) 主要是添加了Page Up、Page Down、光标方向键等击键消息,用于页面翻滚;

    2) 我们没有必要在每个击键消息中添加滚条操作的代码,而只要在WM_KEYDOWN消息中使用SendMessage函数传递假的WM_SCROLL消息给窗口来模拟滚条消息即可,这样就可以让滚条消息响应只处理滚条消息,这样分工明确,不会让代码冗余杂乱;

    3) 关于SendMessage函数的用法:

SendMessage( hWnd, message, wParam, lParam );

直接将一条消息按照参数指定的那样包装成MSG结构体发送给响应的窗口hWnd处,hWnd可以不是产生该消息的窗口,可以是该程序的其它窗口甚至是其它程序的窗口(程序间的通信);

在这里这需要这样使用即可:

case WM_KEYDOWN:
	switch ( wParam )
	{
	case VK_HOME:
		SendMessage( hWnd, WM_VSCROLL, SB_TOP, 0 );
		break;
	....
	}
...
     4) 具体代码:

// sysmets4.c

#include <windows.h>

#include "sysmets.h"

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );

int WINAPI WinMain(
	HINSTANCE	hInstance,
	HINSTANCE	hPreInstanc,
	LPSTR		lpszCmdLine,
	int			nCmdShow
	)
{
	static TCHAR	szAppName[] = TEXT("sysmets4");

	WNDCLASS	wndclass;
	HWND		hWnd;
	MSG			msg;

	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;

	RegisterClass( &wndclass );

	hWnd = CreateWindow(
		szAppName, TEXT("Get System Metrics Version 4"),
		WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
		CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, hInstance, NULL
	);

	ShowWindow( hWnd, nCmdShow );
	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 )
{
	static int		cxChar, cxCaps, cyChar;
	static int		cxClient, cyClient;
	static int		nMaxWidth, nMaxHeight;

	TCHAR	szBuffer[10];

	HDC				hdc;
	PAINTSTRUCT		ps;
	TEXTMETRIC		tm;
	SCROLLINFO		si;

	int		iPreVertPos, iPreHorzPos;
	int		iCurVertPos, iCurHorzPos;
	int		iBeginPaint, iEndPaint;

	int		i;
	int		x, y;

	switch ( message )
	{
	case WM_CREATE:
		hdc = GetDC( hWnd );

		GetTextMetrics( hdc, &tm );
		cxChar = tm.tmAveCharWidth;
		cxCaps = ( tm.tmPitchAndFamily & 1 ? 3 : 2 ) * cxChar / 2;
		cyChar = tm.tmHeight + tm.tmExternalLeading;

		ReleaseDC( hWnd, hdc );

		nMaxWidth  = 2 + ( 22 * cxCaps + 40 * cxChar ) / cxChar;
		nMaxHeight = NUMLINES - 1;

		return 0;

	case WM_SIZE:
		cxClient = LOWORD( lParam );
		cyClient = HIWORD( lParam );

		si.cbSize	= sizeof( SCROLLINFO );
		si.fMask	= SIF_RANGE | SIF_PAGE;
		si.nMin		= 0;
		si.nMax		= nMaxHeight;
		si.nPage	= cyClient / cyChar;
		SetScrollInfo( hWnd, SB_VERT, &si, TRUE );

		si.cbSize	= sizeof( SCROLLINFO );
		si.fMask	= SIF_RANGE | SIF_PAGE;
		si.nMin		= 0;
		si.nMax		= nMaxWidth;
		si.nPage	= cxClient / cxChar;
		SetScrollInfo( hWnd, SB_HORZ, &si, TRUE );

		return 0;

	case WM_VSCROLL:
		si.fMask = SIF_ALL;
		GetScrollInfo( hWnd, SB_VERT, &si );

		iPreVertPos = si.nPos;

		switch ( LOWORD( wParam ) )
		{
		case SB_TOP: // 在滚条上直接用鼠标操作并不会产生这样的消息
					 // 这样的消息只有通过WM_KEYDOWN中通过SendMessage产生
			si.nPos = si.nMin;
			break;

		case SB_BOTTOM:
			si.nPos = si.nMax;
			break;

		case SB_LINEUP:
			si.nPos--;
			break;

		case SB_LINEDOWN:
			si.nPos++;
			break;

		case SB_PAGEUP:
			si.nPos -= si.nPage;
			break;

		case SB_PAGEDOWN:
			si.nPos += si.nPage;
			break;

		case SB_THUMBTRACK:
			si.nPos = si.nTrackPos;
			break;
		}

		si.cbSize	= sizeof( SCROLLINFO );
		si.fMask	= SIF_POS;
		SetScrollInfo( hWnd, SB_VERT, &si, TRUE );
		GetScrollInfo( hWnd, SB_VERT, &si );

		if ( si.nPos != iPreVertPos )
		{
			ScrollWindow( hWnd, 0, cyChar * ( iPreVertPos - si.nPos ), NULL, NULL );
		}

		return 0;

	case WM_HSCROLL:

		si.fMask = SIF_ALL;
		GetScrollInfo( hWnd, SB_HORZ, &si );

		iPreHorzPos = si.nPos;

		switch ( LOWORD( wParam ) )
		{
		case SB_LEFT:
			si.nPos = si.nMin;
			break;

		case SB_RIGHT:
			si.nPos = si.nMax;
			break;

		case SB_LINELEFT:
			si.nPos--;
			break;

		case SB_LINERIGHT:
			si.nPos++;
			break;

		case SB_PAGELEFT:
			si.nPos -= si.nPage;
			break;

		case SB_PAGERIGHT:
			si.nPos += si.nPage;
			break;
			
		case SB_THUMBTRACK:
			si.nPos = si.nTrackPos;
			break;
		}

		si.cbSize	= sizeof( SCROLLINFO );
		si.fMask	= SIF_POS;
		SetScrollInfo( hWnd, SB_HORZ, &si, TRUE );
		GetScrollInfo( hWnd, SB_HORZ, &si );

		if ( si.nPos != iPreHorzPos )
		{
			ScrollWindow( hWnd, cxChar * ( iPreHorzPos - si.nPos ), 0, NULL, NULL );
		}

		return 0;

	case WM_KEYDOWN:
		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: // 上一页,Page Up
			SendMessage( hWnd, WM_VSCROLL, SB_PAGEUP, 0 );
			break;

		case VK_NEXT: // 下一页,P
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值