lislab.c

来自「一本已经绝版的好书」· C语言 代码 · 共 469 行

C
469 行
字号
/*************************************************************
Module name: LISLab.C
Notices: Copyright (c) 1995-1997 Jeffrey Richter
*************************************************************/


#include "..\CmnHdr.H"                  /* See Appendix C. */
#include <windows.h>
#include <windowsx.h>
#include <tchar.h>
#include <string.h>
#include <stdio.h>             // For sprintf
#include "Resource.H"


//////////////////////////////////////////////////////////////


#define TIMER_DELAY (1 * 1000) // 1 second * 1000 milliseconds

UINT  g_uTimerId = 1;
int   g_nEventId = 0;
DWORD g_dwEventTime = 0;
HWND  g_hwndSubject = NULL;
HWND  g_hwndNotepad = NULL;


//////////////////////////////////////////////////////////////


void CalcWndText (HWND hwnd, LPTSTR 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));

   _stprintf(szBufT, __TEXT("[%s] %s"), (LPTSTR) szClass,
      (*szCaption == 0) ? (LPTSTR) __TEXT("(no caption)")
      : (LPTSTR) 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, *LPWALKWINDOWTREEDATA;


void WalkWindowTreeRecurse (LPWALKWINDOWTREEDATA pWWT) {

   const int nIndexAmount = 2;
   HWND hwndChild;

   pWWT->nLevel++;

   if (!IsWindow(pWWT->hwndParent))
      return;

   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);

   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) {

   HWND hwndT;

   // Associate an icon with the dialog box.
   chSETDLGICONS(hwnd, IDI_LISLAB, IDI_LISLAB);

   // Associate the Up arrow cursor with the dialog box's client area
   SetClassLong(hwnd, GCL_HCURSOR, 
      (LONG) LoadCursor(NULL, IDC_UPARROW));

   g_uTimerId = SetTimer(hwnd, g_uTimerId, TIMER_DELAY, NULL);

   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 
   // and the windows of the Explorer.

   // First our own dialog box
   hwndT = GetDlgItem(hwnd, IDC_WNDS);
   ListBox_AddString(hwndT,
      __TEXT("---> This dialog box <---"));

   ListBox_SetItemData(hwndT, 0, hwnd);
   ListBox_SetCurSel(hwndT, 0);

   // Now the windows of the Program Manager
   g_hwndNotepad = FindWindow(__TEXT("Notepad"), NULL);
   WalkWindowTree(hwndT, g_hwndNotepad);

   return(TRUE);
}


//////////////////////////////////////////////////////////////


void Dlg_OnDestroy (HWND hwnd) {
   if (g_uTimerId != 0)
      KillTimer(hwnd, g_uTimerId);
}


//////////////////////////////////////////////////////////////


void Dlg_OnCommand (HWND hwnd, int id, HWND hwndCtl,
   UINT codeNotify) {

   HWND hwndT;
   RECT rc;

   switch (id) {

      case IDCANCEL:
         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_SETCLIPRECT:
         SetRect(&rc, 0, 0, 
            GetSystemMetrics(SM_CXSCREEN) / 2, 
            GetSystemMetrics(SM_CYSCREEN) / 2);
         ClipCursor(&rc);
         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;
   }
}


//////////////////////////////////////////////////////////////


void AddStr (HWND hwndLB, LPCTSTR 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];
   _stprintf(szBuf,
      __TEXT("Capture=%-3s, Msg=RButtonDown, ")
      __TEXT("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];
   _stprintf(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];
   _stprintf(szBuf,
      __TEXT("Capture=%-3s, Msg=LButtonDown, ")
      __TEXT("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];

   _stprintf(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];

   _stprintf(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];
   RECT rc;
   HWND hwndT;

   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);

   GetClipCursor(&rc);
   _stprintf(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;

   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"));
}


//////////////////////////////////////////////////////////////


BOOL CALLBACK Dlg_Proc (HWND hwnd, UINT uMsg,
   WPARAM wParam, LPARAM lParam) {

   switch (uMsg) {
      chHANDLE_DLGMSG(hwnd, WM_INITDIALOG,     Dlg_OnInitDialog);
      chHANDLE_DLGMSG(hwnd, WM_DESTROY,        Dlg_OnDestroy);
      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 hinstPrev, LPTSTR pszCmdLine, int nCmdShow) {

   chWARNIFUNICODEUNDERWIN95();
   DialogBox(hinstExe, MAKEINTRESOURCE(IDD_LISLAB),
      NULL, Dlg_Proc);

   return(0);
}


//////////////////////// End Of File /////////////////////////

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?