|
|
/*
* hotkey.c * * Copyright (c) 1991, Microsoft Corporation * * DESCRIPTION * * This file is for support of program manager under NT Windows. * This file is/was ported from hotkey.c (program manager). * * MODIFICATION HISTORY * Initial Version: x/x/90 Author Unknown, since he didn't feel * like commenting the code... * * NT 32b Version: 1/18/91 Jeff Pack * Intitial port to begin. * * */
#include "progman.h"
#define HK_SHIFT 0x0100
#define HK_CONTROL 0x0200
#define HK_ALT 0x0400
#define HK_EXT 0x0800
#define F_EXT 0x01000000L
TCHAR szHotKey[] = TEXT("pmhotkey");
typedef struct HOTKEYWINDOWBYTES { UINT hotkey; int cyFont; HFONT hfont; } HOTKEYWINDOWBYTES;
#define HWL_HOTKEY FIELD_OFFSET(HOTKEYWINDOWBYTES, hotkey)
#define HWL_CYFONT FIELD_OFFSET(HOTKEYWINDOWBYTES, cyFont)
#define HWLP_FONT FIELD_OFFSET(HOTKEYWINDOWBYTES, hfont)
/*** SetHotKey --
* * * void APIENTRY SetHotKey(HWND hwnd, WORD hk) * * ENTRY - HWND hWnd * WORD hk * * EXIT - void * * SYNOPSIS - ??? * * WARNINGS - * EFFECTS - * */
void APIENTRY SetHotKey(HWND hwnd, WPARAM hk) {
/* don't invalidate if it's the same
*/ if((LONG)hk == GetWindowLong(hwnd, HWL_HOTKEY)){ return; } SetWindowLong(hwnd, HWL_HOTKEY, (LONG)hk);
InvalidateRect(hwnd,NULL,TRUE); }
/*** GetKeyName --
* * * void APIENTRY GetKeyName(WORD vk, PSTR psz, BOOL fExt) * * ENTRY - WORD hk * PSTR psz * BOOL fExt * * EXIT - void * * SYNOPSIS - ??? * * WARNINGS - * EFFECTS - * */
void APIENTRY GetKeyName(UINT vk, LPTSTR psz, BOOL fExt) { LONG scan; scan = (LONG)MapVirtualKey(vk,0) << 16; if (fExt){ scan |= F_EXT; }
GetKeyNameText(scan,psz,50); }
/*** PaintHotKey --
* * * void APIENTRY PaintHotKey(register HWND hwnd) * * ENTRY - HWND hWnd * * EXIT - void * * SYNOPSIS - ??? * * WARNINGS - * EFFECTS - * */
void APIENTRY PaintHotKey(register HWND hwnd) { TCHAR sz[128]; TCHAR szPlus[10]; WORD cch; WORD hk; register HDC hdc; #ifndef ORGCODE
SIZE size; #endif
PAINTSTRUCT ps; int x, y; HANDLE hFont; DWORD dwColor;
LoadString(hAppInstance, IDS_PLUS, szPlus, CharSizeOf(szPlus));
if(hk = (WORD)GetWindowLong(hwnd, HWL_HOTKEY)){ sz[0] = 0; cch = 0; if (hk & HK_CONTROL){ GetKeyName(VK_CONTROL,sz,FALSE); lstrcat(sz,szPlus); } if (hk & HK_SHIFT){ GetKeyName(VK_SHIFT, sz + lstrlen(sz), FALSE); lstrcat(sz,szPlus); } if (hk & HK_ALT){ GetKeyName(VK_MENU, sz + lstrlen(sz), FALSE); lstrcat(sz,szPlus); } GetKeyName((UINT)LOBYTE(hk), sz + lstrlen(sz), hk & HK_EXT); } else{ LoadString(hAppInstance,IDS_NONE,sz,100); }
cch = (WORD)lstrlen(sz); HideCaret(hwnd);
hdc = BeginPaint(hwnd,&ps);
SetBkMode(hdc, TRANSPARENT);
hFont = SelectObject(hdc,(HANDLE)GetWindowLongPtr(hwnd,HWLP_FONT)); x = GetSystemMetrics(SM_CXBORDER); y = GetSystemMetrics(SM_CYBORDER);
if (IsWindowEnabled(hwnd)){ dwColor = GetSysColor(COLOR_WINDOWTEXT); dwColor = SetTextColor(hdc,dwColor); TextOut(hdc,x,y,sz,cch); } else if (dwColor = GetSysColor(COLOR_GRAYTEXT)){ dwColor = SetTextColor(hdc,dwColor); TextOut(hdc,x,y,sz,cch); SetTextColor(hdc,dwColor); } else{ GrayString(hdc,NULL,NULL,(LPARAM)(LPTSTR)sz,cch,x,y,0,0); }
#ifdef ORGCODE
x = (WORD)GetTextExtentPoint(hdc,sz,cch); #else
/*Used to return x/y in DWORD, now returns cx,cy in size*/ GetTextExtentPoint(hdc, sz, cch, &size); x = size.cx; #endif
if (GetFocus() == hwnd) SetCaretPos(x+GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER)); ShowCaret(hwnd);
if (hFont){ SelectObject(hdc,hFont); }
SetBkMode(hdc, OPAQUE);
EndPaint(hwnd,&ps); }
/*** HotKeyWndProc --
* * * LRESULT APIENTRY HotKeyWndProc(register HWND hwnd, UINT wMsg, * register WPARAM wParam, LPARAM lParam) * * ENTRY - HWND hWnd * WORD wMsg * WPARAM wParam * LPARAM lParam * EXIT - LRESULT xxx - returns info, or zero, for nothing to return * * SYNOPSIS - ??? * * WARNINGS - * EFFECTS - * */
LRESULT APIENTRY HotKeyWndProc(register HWND hwnd, UINT wMsg, register WPARAM wParam, LPARAM lParam) { HDC hdc; WORD wT; #ifndef ORGCODE
SIZE size; #endif
switch (wMsg){ case WM_CREATE: SetHotKey(hwnd,0); SendMessage(hwnd,WM_SETFONT,(WPARAM)GetStockObject(SYSTEM_FONT),0L); break;
case WM_SETFOCUS: InvalidateRect(hwnd,NULL,TRUE); CreateCaret(hwnd,NULL,0,GetWindowLong(hwnd,HWL_CYFONT)); ShowCaret(hwnd); break;
case WM_KILLFOCUS: if (!LOBYTE(GetWindowLong(hwnd,HWL_HOTKEY))){ SetHotKey(hwnd,0); } DestroyCaret(); break;
case WM_GETDLGCODE: return DLGC_WANTCHARS | DLGC_WANTARROWS;
case WM_SETTEXT: SetHotKey(hwnd,LOWORD(lParam)); break;
case WM_GETTEXT: *(LPINT)lParam = GetWindowLong(hwnd,HWL_HOTKEY); break;
case WM_SETHOTKEY: SetHotKey(hwnd,(WPARAM) wParam); break;
case WM_GETHOTKEY: return GetWindowLong(hwnd,HWL_HOTKEY);
case WM_LBUTTONDOWN: SetFocus(hwnd); break;
case WM_SYSKEYDOWN: case WM_KEYDOWN: switch (wParam) { case VK_RETURN: case VK_TAB: case VK_SPACE: case VK_DELETE: case VK_ESCAPE: case VK_BACK: SetHotKey(hwnd,0); return DefWindowProc(hwnd,wMsg,wParam,lParam); case VK_MENU: case VK_SHIFT: case VK_CONTROL: wParam = 0; /*** fall thru ***/
default: if (GetKeyState(VK_CONTROL) < 0) wParam |= HK_CONTROL; if (GetKeyState(VK_SHIFT) < 0) wParam |= HK_SHIFT; if (GetKeyState(VK_MENU) < 0) wParam |= HK_ALT; if (lParam & F_EXT) wParam |= HK_EXT;
// more than one shift key must be specified. That is,
// CONTROL+ALT, CONTROL+SHIFT, SHIFT+ALT
// get the bitmask of shift keys and then determine whether
// it has at least two bits set via the bitcount trick
// if not enough control things are present we add them
// in. so the user gets the idea.
if ((wParam & HK_ALT) && !(wParam & HK_CONTROL) && !(wParam & HK_SHIFT)) { break; } else { wT = (WORD)(wParam & (HK_CONTROL|HK_SHIFT|HK_ALT)); if (!wT || !(wT & (wT - 1))) wParam |= HK_CONTROL | HK_ALT;
SetHotKey(hwnd,wParam); break; } } break;
case WM_SYSKEYUP: case WM_CHAR: case WM_SYSCHAR: case WM_KEYUP: if (!LOBYTE((WORD)GetWindowLong(hwnd,HWL_HOTKEY))) SetHotKey(hwnd,0); break;
case WM_GETFONT: return GetWindowLongPtr(hwnd,HWLP_FONT);
case WM_SETFONT: lParam = GetWindowLongPtr(hwnd,HWLP_FONT); SetWindowLongPtr(hwnd,HWLP_FONT,wParam); hdc = GetDC(hwnd); wParam = (WPARAM) SelectObject(hdc,(HANDLE)wParam); GetTextExtentPoint(hdc, TEXT("C"), 1, &size); SetWindowLong(hwnd, HWL_CYFONT, size.cy); if (wParam){ SelectObject(hdc,(HANDLE)wParam); } ReleaseDC(hwnd,hdc); InvalidateRect(hwnd,NULL,TRUE); return lParam;
case WM_PAINT: PaintHotKey(hwnd); break;
case WM_ERASEBKGND: HideCaret(hwnd); lParam = DefWindowProc(hwnd,wMsg,wParam,lParam); ShowCaret(hwnd); return lParam;
default: return DefWindowProc(hwnd,wMsg,wParam,lParam); } return 0L; }
/*** RegisterHotKeyClass --
* * * BOOL APIENTRY RegisterHotKeyClass(HANDLE hInstance) * * ENTRY - HWND HANDLE hInstance * EXIT - BOOL xxx - returns return code from RegisterClass * * SYNOPSIS - ??? * * WARNINGS - This (under 16) took hInstance. Under win32, hInstance is * NULL, cause there is only one instance. * EFFECTS - * */
BOOL APIENTRY RegisterHotKeyClass(HANDLE hInstance) { WNDCLASS wc;
wc.style = 0; wc.lpfnWndProc = HotKeyWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = sizeof(HOTKEYWINDOWBYTES); wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = NULL; wc.lpszClassName = szHotKey;
return RegisterClass(&wc); }
|