www.pudn.com > NumPanel.rar > np_orig.cpp
//====================================================================== // NumPanel - An IM window // // Written for the book Programming Windows CE // Copyright (C) 2003 Douglas Boling //====================================================================== #include// For all that Windows stuff #define COBJMACROS #include // SIP includes #include // Keyboard flag includes #include "NumPanel.h" // Includes for this window extern "C" HINSTANCE hInst; // // Local variables for number panel // TCHAR g_tcBtnChar[] = { TEXT('1'), TEXT('2'), TEXT('3'), TEXT('-'), TEXT('*'), TEXT('4'), TEXT('5'), TEXT('6'), TEXT('+'), TEXT('/'), TEXT('7'), TEXT('8'), TEXT('9'), TEXT('0'), TEXT('='), }; UINT g_BtnVChars[] = { '1', '2', '3', VK_HYPHEN, VK_MULTIPLY, '4', '5', '6', VK_ADD, VK_SLASH, '7', '8', '9', '0', VK_EQUAL, }; // Message dispatch table for SipWindowProc const struct decodeUINT SipMessages[] = { WM_CREATE, DoCreateSip, WM_PAINT, DoPaintSip, MYMSG_METHCALL, DoSetSipInfo, WM_LBUTTONDOWN, DoMouseSip, WM_MOUSEMOVE, DoMouseSip, WM_LBUTTONUP, DoMouseSip, WM_LBUTTONDBLCLK, DoMouseSip, WM_DESTROY, DoDestroySip, }; //---------------------------------------------------------------------- // CreateIMWindow - Create the input method window. // HWND CreateIMWindow (HWND hwndParent) { WNDCLASS wc; RECT rect; HWND hwnd; // Register sip window class. memset (&wc, 0, sizeof (wc)); wc.style = CS_DBLCLKS; wc.lpfnWndProc = NPWndProc; // Callback function wc.hInstance = hInst; // Owner handle wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wc.lpszClassName = MYSIPCLS; // Window class name if (RegisterClass (&wc) == 0) return 0; // Create SIP window. GetClientRect (hwndParent, &rect); hwnd = CreateWindowEx (0, MYSIPCLS, TEXT(""), WS_VISIBLE | WS_CHILD | WS_BORDER, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hwndParent, (HMENU)100, hInst, 0); if (!IsWindow (hwnd)) return 0; return hwnd; } //---------------------------------------------------------------------- // DestroyIMWindow - Destroy the input method window. // int DestroyIMWindow (HWND hwnd) { // Clean up since we're about to be unloaded. DestroyWindow (hwnd); UnregisterClass (MYSIPCLS, hInst); return 0; } //====================================================================== // NPWndProc - Window procedure for SIP // LRESULT CALLBACK NPWndProc (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { INT i; // Call routine to handle control message. for (i = 0; i < dim(SipMessages); i++) { if (wMsg == SipMessages[i].Code) return (*SipMessages[i].Fxn)(hWnd, wMsg, wParam, lParam); } return DefWindowProc (hWnd, wMsg, wParam, lParam); } //---------------------------------------------------------------------- // DoCreateSip - Process WM_CREATE message for window. // LRESULT CALLBACK DoCreateSip (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { LPSIPWNDSTRUCT pWndData; // Allocate a data structure for the sip keyboard window. pWndData = (LPSIPWNDSTRUCT)LocalAlloc (LPTR, sizeof (SIPWNDSTRUCT)); if (!pWndData) { DestroyWindow (hWnd); return 0; } memset (pWndData, 0, sizeof (SIPWNDSTRUCT)); GetWindowRect (GetParent (hWnd), &pWndData->rectDocked); pWndData->rectLast.left = -1; SetWindowLong (hWnd, GWL_USERDATA, (INT)pWndData); return 0; } //---------------------------------------------------------------------- // DoSetSipInfo - Process set information user message for window. // LRESULT CALLBACK DoSetSipInfo (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { LPSIPWNDSTRUCT pWndData; RECT rect; pWndData = (LPSIPWNDSTRUCT)GetWindowLong (hWnd, GWL_USERDATA); switch (wParam) { // Called when RegisterCallback method called case MSGCODE_REGCALLBACK: pWndData->pIMCallback = (IIMCallback *)lParam; break; // Called when GetInfo method called case MSGCODE_GETINFO: pWndData->imi = *(IMINFO *)lParam; break; // Called when ReceiveSipInfo method called case MSGCODE_SETINFO: GetClientRect (GetParent(hWnd), &rect); MoveWindow (hWnd, 0, 0, rect.right - rect.left, rect.bottom - rect.top, TRUE); break; // Called when RegisterCallback2 method called case MSGCODE_REGCALLBACK2: pWndData->pIMCallback2 = (IIMCallback2 *)lParam; break; } return 0; } //---------------------------------------------------------------------- // DoPaintSip - Process WM_PAINT message for window. // LRESULT CALLBACK DoPaintSip (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; HBRUSH hOld; PAINTSTRUCT ps; RECT rect, rectBtn; INT i, j, k, x, y, cx, cy, cxBtn, cyBtn; LPSIPWNDSTRUCT pWndData; pWndData = (LPSIPWNDSTRUCT)GetWindowLong (hWnd, GWL_USERDATA); hdc = BeginPaint (hWnd, &ps); GetClientRect (hWnd, &rect); cx = (rect.right - rect.left - 3 - GRIPWIDTH) / CXBTNS; cy = (rect.bottom - rect.top - 3) / CYBTNS; cxBtn = cx - 3; cyBtn = cy - 3; // Select a brush for the gripper. hOld = (HBRUSH)SelectObject (hdc, GetStockObject (GRAY_BRUSH)); Rectangle (hdc, rect.left, rect.top, rect.left + GRIPWIDTH, rect.bottom); SelectObject (hdc, hOld); k = 0; y = 3; for (i = 0; i < CYBTNS; i++) { x = 3 + GRIPWIDTH; for (j = 0; j < CXBTNS; j++) { SetRect (&rectBtn, x, y, x + cxBtn, y + cyBtn); DrawButton (hdc, &rectBtn, &g_tcBtnChar[k], pWndData->dwBtnDnFlags & (1 << k)); k++; x += cx; } y += cy; } EndPaint (hWnd, &ps); return 0; } //---------------------------------------------------------------------- // ComputeFloatRect - Compute the location and size of the drag rect. // int ComputeFloatRect (HWND hwnd, LPSIPWNDSTRUCT pWndData, POINT pt, RECT *prectOut) { pt.x -= pWndData->ptMovBasis.x; pt.y -= pWndData->ptMovBasis.y; prectOut->right = FLOATWIDTH; prectOut->bottom = FLOATHEIGHT; prectOut->left = pt.x; prectOut->top = pt.y; prectOut->right += pt.x; prectOut->bottom += pt.y; return 0; } //---------------------------------------------------------------------- // DrawFloatRect - Draw a drag rectangle by XORing the desktop. // int DrawFloatRect (HWND hWnd, RECT rect) { HDC hdc; HBRUSH hbrOld; HPEN hpenOld; int nOldMode; // Get the DC. Set ROP, brush, and pen. hdc = GetDC (NULL); nOldMode = SetROP2 (hdc, R2_NOT); hbrOld = (HBRUSH)SelectObject (hdc, GetStockObject (NULL_BRUSH)); hpenOld = (HPEN)SelectObject (hdc, GetStockObject (BLACK_PEN)); Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom); SelectObject (hdc, hbrOld); SelectObject (hdc, hpenOld); SetROP2 (hdc, nOldMode); ReleaseDC (NULL, hdc); return 0; } //---------------------------------------------------------------------- // HandleGripper - Handles mouse messages over gripper bar // LRESULT HandleGripper (HWND hWnd, LPSIPWNDSTRUCT pWndData, UINT wMsg, LPARAM lParam) { POINT pt; RECT rectFloat; pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam); switch (wMsg) { case WM_LBUTTONDOWN: if (pt.x > GRIPWIDTH+3) return 0; SetCapture (hWnd); pWndData->fMoving = TRUE; pWndData->ptMovBasis = pt; ClientToScreen (hWnd, &pt); pWndData->ptMovStart = pt; ShowWindow (GetParent(hWnd), SW_HIDE); break; case WM_MOUSEMOVE: if (!pWndData->fMoving) return 0; ClientToScreen (hWnd, &pt); ComputeFloatRect (hWnd, pWndData, pt, &rectFloat); // Erase old drag rectangle. if (pWndData->rectLast.left != -1) DrawFloatRect (hWnd, pWndData->rectLast); // Draw new drag rectangle. DrawFloatRect (hWnd, rectFloat); pWndData->rectLast = rectFloat; break; case WM_LBUTTONUP: if (!pWndData->fMoving) return 0; // Free up dragging stuff. ReleaseCapture(); pWndData->fMoving = FALSE; ClientToScreen (hWnd, &pt); // Erase last drag rectangle. ComputeFloatRect (hWnd, pWndData, pt, &rectFloat); if (pWndData->rectLast.left != -1) DrawFloatRect (hWnd, pWndData->rectLast); pWndData->rectLast.left = -1; ShowWindow (GetParent(hWnd), SW_SHOW); // Don't move SIP if really small move. if ((abs (pWndData->ptMovStart.x - pt.x) < 3) && (abs (pWndData->ptMovStart.y - pt.y) < 3)) break; // Tell the Input Manager about the move. pWndData->imi.rcSipRect = rectFloat; pWndData->imi.fdwFlags &= ~SIPF_DOCKED; pWndData->imi.fdwFlags |= SIPF_ON; pWndData->pIMCallback->SetImInfo(&pWndData->imi); break; case WM_LBUTTONDBLCLK: if (pt.x > GRIPWIDTH+3) return 0; ReleaseCapture(); pWndData->fMoving = FALSE; // Embedded SIP manager doesn't use SIPF_DOCKED so only use on PPC. #if defined(WIN32_PLATFORM_PSPC) pWndData->imi.fdwFlags |= (SIPF_DOCKED | SIPF_ON); #endif pWndData->imi.rcSipRect = pWndData->rectDocked; pWndData->pIMCallback->SetImInfo(&pWndData->imi); break; } pWndData->dwBtnDnFlags = 0; // If we moved, no buttons down. return 1; } //---------------------------------------------------------------------- // DoMouseSip - Process mouse button messages for window. WM_LBUTTONDOWN // LRESULT CALLBACK DoMouseSip (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { RECT rect; INT i, x, y, cx, cy; UINT nChar, unShiftFlags = 0; DWORD BtnDnFlags; LPSIPWNDSTRUCT pWndData; pWndData = (LPSIPWNDSTRUCT)GetWindowLong (hWnd, GWL_USERDATA); // See if moving gripper or gripper tap. if (HandleGripper (hWnd, pWndData, wMsg, lParam)) return 0; // Compute the button grid. GetClientRect (hWnd, &rect); cx = (rect.right - rect.left - 3 - GRIPWIDTH) / CXBTNS; cy = (rect.bottom - rect.top - 3) / CYBTNS; x = ((LOWORD (lParam)-3-GRIPWIDTH) / cx); y = ((HIWORD (lParam)-3) / cy); i = (y * CXBTNS) + x; // i now contains btn index. // Do small amount of message-specific processing. switch (wMsg) { case WM_LBUTTONDOWN: SetCapture (hWnd); // Fall through to WM_MOUSEMOVE case. case WM_MOUSEMOVE: BtnDnFlags = 1 << i; break; case WM_LBUTTONDBLCLK: case WM_LBUTTONUP: if (pWndData->dwBtnDnFlags) ReleaseCapture(); BtnDnFlags = 0; nChar = g_tcBtnChar[i]; pWndData->pIMCallback->SendCharEvents(g_BtnVChars[i], KeyStateDownFlag, 1, &nShiftFlags, &nChar); break; } // Decide how to repaint wnd. If only 1 btn changed, just // invalidate that rect. Otherwise, invalidate entire wnd. if ((wMsg == WM_MOUSEMOVE) && (BtnDnFlags !=pWndData->dwBtnDnFlags)) InvalidateRect (hWnd, NULL, FALSE); else { i = 3+GRIPWIDTH; // Compensate for the gripper on left side. SetRect (&rect, x*cx+i, y*cy, (x+1)*cx+i, (y+1)*cy); InvalidateRect (hWnd, &rect, FALSE); } pWndData->dwBtnDnFlags = BtnDnFlags; return 0; } //---------------------------------------------------------------------- // DoDestroySip - Process WM_DESTROY message for window. // LRESULT CALLBACK DoDestroySip (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { LPSIPWNDSTRUCT pWndData; pWndData = (LPSIPWNDSTRUCT)GetWindowLong (hWnd, GWL_USERDATA); LocalFree (pWndData); return 0; } //--------------------------------------------------------------------- // DrawButton - Draws a button // INT DrawButton (HDC hdc, RECT *prect, LPTSTR pChar, BOOL fPressed) { if (!fPressed) { SelectObject (hdc, GetStockObject (BLACK_PEN)); SelectObject (hdc, GetStockObject (WHITE_BRUSH)); SetBkColor (hdc, RGB (255, 255, 255)); SetTextColor (hdc, RGB (0, 0, 0)); } else { SelectObject (hdc, GetStockObject (BLACK_BRUSH)); SelectObject (hdc, GetStockObject (WHITE_PEN)); SetTextColor (hdc, RGB (255, 255, 255)); SetBkColor (hdc, RGB (0, 0, 0)); } Rectangle (hdc, prect->left, prect->top, prect->right, prect->bottom); Rectangle (hdc, prect->left+1, prect->top+1, prect->right+1, prect->bottom+1); DrawText (hdc, pChar, 1, prect, DT_CENTER|DT_VCENTER|DT_SINGLELINE); return 0; }