第27章 硬體輸入模型和區域性輸入狀態
阿新 • • 發佈:2019-02-06
/****************************************************************************** Module: LISLab.cpp Notices: Copyright (c) 2000 Jeffrey Richter ******************************************************************************/ #include "..\CmnHdr.h" /* See Appendix A. */ #include <windowsx.h> #include <tchar.h> #include <string.h> #include "Resource.h" /////////////////////////////////////////////////////////////////////////////// #define TIMER_DELAY (500) // Half a second UINT_PTR g_uTimerId = 1; int g_nEventId = 0; DWORD g_dwEventTime = 0; HWND g_hwndSubject = NULL; HWND g_hwndNotepad = NULL; /////////////////////////////////////////////////////////////////////////////// void CalcWndText(HWND hwnd, PTSTR szBuf, int nLen) { TCHAR szClass[50], szCaption[50], szBufT[150]; if (hwnd == (HWND) NULL) { _tcscpy(szBuf, TEXT("(no window)")); return; } if (!IsWindow(hwnd)) { _tcscpy(szBuf, TEXT("(invalid window)")); return; } GetClassName(hwnd, szClass, chDIMOF(szClass)); GetWindowText(hwnd, szCaption, chDIMOF(szCaption)); wsprintf(szBufT, TEXT("[%s] %s"), (PTSTR) szClass, (*szCaption == 0) ? (PTSTR) TEXT("(no caption)") : (PTSTR) szCaption); _tcsncpy(szBuf, szBufT, nLen - 1); szBuf[nLen - 1] = 0; // Force zero-terminated string } /////////////////////////////////////////////////////////////////////////////// // To minimize stack use, one instance of WALKWINDOWTREEDATA // is created as a local variable in WalkWindowTree() and a // pointer to it is passed to WalkWindowTreeRecurse. // Data used by WalkWindowTreeRecurse typedef struct { HWND hwndLB; // Handle to the output list box HWND hwndParent; // Handle to the parent int nLevel; // Nesting depth int nIndex; // List box item index TCHAR szBuf[100]; // Output buffer int iBuf; // Index into szBuf } WALKWINDOWTREEDATA, *PWALKWINDOWTREEDATA; void WalkWindowTreeRecurse(PWALKWINDOWTREEDATA pWWT) { if (!IsWindow(pWWT->hwndParent)) return; pWWT->nLevel++; const int nIndexAmount = 2; for (pWWT->iBuf = 0; pWWT->iBuf < pWWT->nLevel * nIndexAmount; pWWT->iBuf++) pWWT->szBuf[pWWT->iBuf] = TEXT(' '); CalcWndText(pWWT->hwndParent, &pWWT->szBuf[pWWT->iBuf], chDIMOF(pWWT->szBuf) - pWWT->iBuf); pWWT->nIndex = ListBox_AddString(pWWT->hwndLB, pWWT->szBuf); ListBox_SetItemData(pWWT->hwndLB, pWWT->nIndex, pWWT->hwndParent); HWND hwndChild = GetFirstChild(pWWT->hwndParent); while (hwndChild != NULL) { pWWT->hwndParent = hwndChild; WalkWindowTreeRecurse(pWWT); hwndChild = GetNextSibling(hwndChild); } pWWT->nLevel--; } /////////////////////////////////////////////////////////////////////////////// void WalkWindowTree(HWND hwndLB, HWND hwndParent) { WALKWINDOWTREEDATA WWT; WWT.hwndLB = hwndLB; WWT.hwndParent = hwndParent; WWT.nLevel = -1; WalkWindowTreeRecurse(&WWT); } /////////////////////////////////////////////////////////////////////////////// BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { chSETDLGICONS(hwnd, IDI_LISLAB); // Associate the Up arrow cursor with the dialog box's client area SetClassLongPtr(hwnd, GCLP_HCURSOR, (LONG_PTR) LoadCursor(NULL, IDC_UPARROW)); g_uTimerId = SetTimer(hwnd, g_uTimerId, TIMER_DELAY, NULL); HWND hwndT = GetDlgItem(hwnd, IDC_WNDFUNC); ComboBox_AddString(hwndT, TEXT("SetFocus")); ComboBox_AddString(hwndT, TEXT("SetActiveWindow")); ComboBox_AddString(hwndT, TEXT("SetForegroundWnd")); ComboBox_AddString(hwndT, TEXT("BringWindowToTop")); ComboBox_AddString(hwndT, TEXT("SetWindowPos-TOP")); ComboBox_AddString(hwndT, TEXT("SetWindowPos-BTM")); ComboBox_SetCurSel(hwndT, 0); // Fill the windows list box with our window hwndT = GetDlgItem(hwnd, IDC_WNDS); ListBox_AddString(hwndT, TEXT("---> This dialog box <---")); ListBox_SetItemData(hwndT, 0, hwnd); ListBox_SetCurSel(hwndT, 0); // Now add Notepad's windows g_hwndNotepad = FindWindow(TEXT("Notepad"), NULL); if (g_hwndNotepad == NULL) { // Notepad isn't running; run it. STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; TCHAR szCommandLine[] = TEXT("Notepad"); if (CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { // Wait for Notepad to create all its windows. WaitForInputIdle(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); g_hwndNotepad = FindWindow(TEXT("Notepad"), NULL); } } WalkWindowTree(hwndT, g_hwndNotepad); return(TRUE); } /////////////////////////////////////////////////////////////////////////////// void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { HWND hwndT; switch (id) { case IDCANCEL: if (g_uTimerId != 0) KillTimer(hwnd, g_uTimerId); EndDialog(hwnd, 0); break; case IDC_FUNCSTART: g_dwEventTime = GetTickCount() + 1000 * GetDlgItemInt(hwnd, IDC_DELAY, NULL, FALSE); hwndT = GetDlgItem(hwnd, IDC_WNDS); g_hwndSubject = (HWND) ListBox_GetItemData(hwndT, ListBox_GetCurSel(hwndT)); g_nEventId = ComboBox_GetCurSel(GetDlgItem(hwnd, IDC_WNDFUNC)); SetWindowText(GetDlgItem(hwnd, IDC_EVENTPENDING), TEXT("Pending")); break; case IDC_THREADATTACH: AttachThreadInput(GetWindowThreadProcessId(g_hwndNotepad, NULL), GetCurrentThreadId(), TRUE); break; case IDC_THREADDETACH: AttachThreadInput(GetWindowThreadProcessId(g_hwndNotepad, NULL), GetCurrentThreadId(), FALSE); break; case IDC_REMOVECLIPRECT: ClipCursor(NULL); break; case IDC_HIDECURSOR: ShowCursor(FALSE); break; case IDC_SHOWCURSOR: ShowCursor(TRUE); break; case IDC_INFINITELOOP: SetCursor(LoadCursor(NULL, IDC_NO)); for (;;) ; break; case IDC_SETCLIPRECT: RECT rc; SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXSCREEN) / 2, GetSystemMetrics(SM_CYSCREEN) / 2); ClipCursor(&rc); break; } } /////////////////////////////////////////////////////////////////////////////// void AddStr(HWND hwndLB, PCTSTR szBuf) { int nIndex; do { nIndex = ListBox_AddString(hwndLB, szBuf); if (nIndex == LB_ERR) ListBox_DeleteString(hwndLB, 0); } while (nIndex == LB_ERR); ListBox_SetCurSel(hwndLB, nIndex); } /////////////////////////////////////////////////////////////////////////////// int Dlg_OnRButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) { TCHAR szBuf[100]; wsprintf(szBuf, TEXT("Capture=%-3s, Msg=RButtonDown, DblClk=%-3s, x=%5d, y=%5d"), (GetCapture() == NULL) ? TEXT("No") : TEXT("Yes"), fDoubleClick ? TEXT("Yes") : TEXT("No"), x, y); AddStr(GetDlgItem(hwnd, IDC_MOUSEMSGS), szBuf); if (!fDoubleClick) SetCapture(hwnd); else ReleaseCapture(); return(0); } /////////////////////////////////////////////////////////////////////////////// int Dlg_OnRButtonUp(HWND hwnd, int x, int y, UINT keyFlags) { TCHAR szBuf[100]; wsprintf(szBuf, TEXT("Capture=%-3s, Msg=RButtonUp, x=%5d, y=%5d"), (GetCapture() == NULL) ? TEXT("No") : TEXT("Yes"), x, y); AddStr(GetDlgItem(hwnd, IDC_MOUSEMSGS), szBuf); return(0); } /////////////////////////////////////////////////////////////////////////////// int Dlg_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) { TCHAR szBuf[100]; wsprintf(szBuf, TEXT("Capture=%-3s, Msg=LButtonDown, DblClk=%-3s, x=%5d, y=%5d"), (GetCapture() == NULL) ? TEXT("No") : TEXT("Yes"), fDoubleClick ? TEXT("Yes") : TEXT("No"), x, y); AddStr(GetDlgItem(hwnd, IDC_MOUSEMSGS), szBuf); return(0); } /////////////////////////////////////////////////////////////////////////////// void Dlg_OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags) { TCHAR szBuf[100]; wsprintf(szBuf, TEXT("Capture=%-3s, Msg=LButtonUp, x=%5d, y=%5d"), (GetCapture() == NULL) ? TEXT("No") : TEXT("Yes"), x, y); AddStr(GetDlgItem(hwnd, IDC_MOUSEMSGS), szBuf); } /////////////////////////////////////////////////////////////////////////////// void Dlg_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags) { TCHAR szBuf[100]; wsprintf(szBuf, TEXT("Capture=%-3s, Msg=MouseMove, x=%5d, y=%5d"), (GetCapture() == NULL) ? TEXT("No") : TEXT("Yes"), x, y); AddStr(GetDlgItem(hwnd, IDC_MOUSEMSGS), szBuf); } /////////////////////////////////////////////////////////////////////////////// void Dlg_OnTimer(HWND hwnd, UINT id) { TCHAR szBuf[100]; CalcWndText(GetFocus(), szBuf, chDIMOF(szBuf)); SetWindowText(GetDlgItem(hwnd, IDC_WNDFOCUS), szBuf); CalcWndText(GetCapture(), szBuf, chDIMOF(szBuf)); SetWindowText(GetDlgItem(hwnd, IDC_WNDCAPTURE), szBuf); CalcWndText(GetActiveWindow(), szBuf, chDIMOF(szBuf)); SetWindowText(GetDlgItem(hwnd, IDC_WNDACTIVE), szBuf); CalcWndText(GetForegroundWindow(), szBuf, chDIMOF(szBuf)); SetWindowText(GetDlgItem(hwnd, IDC_WNDFOREGROUND), szBuf); RECT rc; GetClipCursor(&rc); wsprintf(szBuf, TEXT("left=%d, top=%d, right=%d, bottom=%d"), rc.left, rc.top, rc.right, rc.bottom); SetWindowText(GetDlgItem(hwnd, IDC_CLIPCURSOR), szBuf); if ((g_dwEventTime == 0) || (GetTickCount() < g_dwEventTime)) return; HWND hwndT; switch (g_nEventId) { case 0: // SetFocus g_hwndSubject = SetFocus(g_hwndSubject); break; case 1: // SetActiveWindow g_hwndSubject = SetActiveWindow(g_hwndSubject); break; case 2: // SetForegroundWindow hwndT = GetForegroundWindow(); SetForegroundWindow(g_hwndSubject); g_hwndSubject = hwndT; break; case 3: // BringWindowToTop BringWindowToTop(g_hwndSubject); break; case 4: // SetWindowPos w/HWND_TOP SetWindowPos(g_hwndSubject, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); g_hwndSubject = (HWND) 1; break; case 5: // SetWindowPos w/HWND_BOTTOM SetWindowPos(g_hwndSubject, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); g_hwndSubject = (HWND) 1; break; } if (g_hwndSubject == (HWND) 1) { SetWindowText(GetDlgItem(hwnd, IDC_PREVWND), TEXT("Can't tell.")); } else { CalcWndText(g_hwndSubject, szBuf, chDIMOF(szBuf)); SetWindowText(GetDlgItem(hwnd, IDC_PREVWND), szBuf); } g_hwndSubject = NULL; g_nEventId = 0; g_dwEventTime = 0; SetWindowText(GetDlgItem(hwnd, IDC_EVENTPENDING), TEXT("Executed")); } /////////////////////////////////////////////////////////////////////////////// INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog); chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand); chHANDLE_DLGMSG(hwnd, WM_MOUSEMOVE, Dlg_OnMouseMove); chHANDLE_DLGMSG(hwnd, WM_LBUTTONDOWN, Dlg_OnLButtonDown); chHANDLE_DLGMSG(hwnd, WM_LBUTTONDBLCLK, Dlg_OnLButtonDown); chHANDLE_DLGMSG(hwnd, WM_LBUTTONUP, Dlg_OnLButtonUp); chHANDLE_DLGMSG(hwnd, WM_RBUTTONDOWN, Dlg_OnRButtonDown); chHANDLE_DLGMSG(hwnd, WM_RBUTTONDBLCLK, Dlg_OnRButtonDown); chHANDLE_DLGMSG(hwnd, WM_RBUTTONUP, Dlg_OnRButtonUp); chHANDLE_DLGMSG(hwnd, WM_TIMER, Dlg_OnTimer); } return(FALSE); } /////////////////////////////////////////////////////////////////////////////// int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) { DialogBox(hinstExe, MAKEINTRESOURCE(IDD_LISLAB), NULL, Dlg_Proc); return(0); } //////////////////////////////// End of File //////////////////////////////////