⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lislab.dpr

📁 一本已经绝版的好书
💻 DPR
字号:

// Module name: LISLab.C ->> LISLab.dpr
// Notices: Copyright (c) 1995-1997 Jeffrey Richter
// Translator: 刘麻子, Liu_mazi@126.com

program LISLab;

{$R 'LISLab.res' 'LISLab.rc'}

uses
  Windows, Messages,
  Other in '..\Other.pas', CmnHdr in '..\CmnHdr.pas', WindowsX in '..\WindowsX.pas';

const
  IDD_LISLAB         =    1;
  IDC_WNDFOCUS       =  100;
  IDC_WNDACTIVE      =  101;
  IDC_WNDFOREGROUND  =  102;
  IDI_LISLAB         =  102;
  IDC_WNDCAPTURE     =  103;
  IDC_CLIPCURSOR     =  104;
  IDC_WNDFUNC        =  105;
  IDC_FUNCSTART      =  106;
  IDC_DELAY          =  107;
  IDC_WNDS           =  110;
  IDC_THREADATTACH   =  111;
  IDC_THREADDETACH   =  112;
  IDC_MOUSEMSGS      =  113;
  IDC_SETCLIPRECT    =  114;
  IDC_REMOVECLIPRECT =  115;
  IDC_HIDECURSOR     =  116;
  IDC_SHOWCURSOR     =  117;
  IDC_EVENTPENDING   =  118;
  IDC_PREVWND        =  119;
  IDC_INFINITELOOP   =  120;

const
  Timer_Delay = 1000;

var
  g_uTimerId: DWORD = 1;
  g_nEventId: DWORD = 0;
  g_dwEventTime: DWORD = 0;
  g_hWndSubject: HWND = 0;
  g_hWndNotepad: HWND = 0;

  // 基本窗口信息
procedure CalcWndText(hWnd: HWND; const szBuf: PChar; nLen: Integer);
var
  szClass, szCaption: array[0..50] of Char;
  szBufT: array[0..150] of Char;
begin
  if (hWnd = 0) then begin lstrcpy(szBuf, '(no window)'); Exit; end;
  if (IsWindow(hWnd) = FALSE) then begin lstrcpy(szBuf, '(invalid window)'); Exit; end;

  GetClassName(hWnd, szClass, chDIMOF(szClass));
  GetWindowText(hWnd, szCaption, chDIMOF(szCaption));    
  _wvsprintf(szBufT, '[%s] %s', [ DWORD(@szClass), DWORD(IfThen(szCaption[0] = #0, '(no caption)', @szCaption)) ]);

  lstrcpyn(szBuf, szBufT, nLen - 1);  
  szBuf[nLen - 1] := #0;
end;

type
  TWalkWindowTreeData = record
    hWndLB: HWND;      // Handle to the output list box
    hWndParent: HWND;  // Handle to the parent
    nLevel: Integer;   // Nesting depth
    nIndex: Integer;   // List box item index
    szBuf: array[0..99] of Char; // Output buffer
    iBuf: Integer;     // Index into szBuf
  end;

  // 递归枚举窗口结构
procedure WalkWindowTreeRecurse(var WWT: TWalkWindowTreeData);
const
  nIndexAmount = 2;
var
  hWndChild: HWND;
  nBlank: Integer;
begin
  if (IsWindow(WWT.hWndParent) = FALSE) then Exit;

  // 层次增加
  Inc(WWT.nLevel);

  // 前缀空格
  WWT.iBuf := 0;
  nBlank := WWT.nLevel * nIndexAmount;
  while (WWT.iBuf < nBlank) do
  begin
    WWT.szBuf[WWT.iBuf] := ' ';
    Inc(WWT.iBuf);
  end;

  // 窗口信息
  CalcWndText(WWT.hWndParent, @WWT.szBuf[WWT.iBuf], chDIMOF(WWT.szBuf) - WWT.iBuf);

  // 添加到ListBox
  WWT.nIndex := ListBox_AddString(WWT.hWndLB, WWT.szBuf);
  ListBox_SetItemData(WWT.hWndLB, WWT.nIndex, WWT.hWndParent);

  // 递归调用
  hWndChild := GetFirstChild(WWT.hWndParent);
  while (hWndChild <> 0) do
  begin
    WWT.hWndParent := hWndChild;
    WalkWindowTreeRecurse(WWT);
    hWndChild := GetNextSibling(hWndChild);
  end;

  // 层次减少
  Dec(WWT.nLevel);
end;

  // 窗口结构 -> ListBox
procedure WalkWindowTree(hWndLB, hWndParent: HWND);
var
  WWT: TWalkWindowTreeData;
begin
  WWT.hWndLB := hWndLB;
  WWT.hWndParent := hWndParent;
  WWT.nLevel := -1;

  WalkWindowTreeRecurse(WWT);
end;

  // WM_INITDIALOG
function Dlg_OnInitDialog(hWnd, hWndFocus: HWND; lParam: LPARAM): BOOL;
var
  hWndT: DWORD; // HWND
begin
  // 设置图标
  chSETDLGICONS(hWnd, IDI_LISLAB, IDI_LISLAB);

  // 设置光标
  SetClassLong(hWnd, GCL_HCURSOR, LoadCursor(0, IDC_UPARROW));

  // 安装时钟
  g_uTimerId := SetTimer(hWnd, g_uTimerId, TIMER_DELAY, nil);

  // 动作列表
  hWndT := GetDlgItem(hWnd, IDC_WNDFUNC);
  ComboBox_AddString(hWndT, 'SetFocus');
  ComboBox_AddString(hWndT, 'SetActiveWindow');
  ComboBox_AddString(hWndT, 'SetForegroundWnd');
  ComboBox_AddString(hWndT, 'BringWindowToTop');
  ComboBox_AddString(hWndT, 'SetWindowPos-TOP');
  ComboBox_AddString(hWndT, 'SetWindowPos-BTM');
  ComboBox_SetCurSel(hWndT, 0);

  // 窗口列表
  hWndT := GetDlgItem(hWnd, IDC_WNDS);
  ListBox_AddString(hWndT, '---> This dialog box <---');
  ListBox_SetItemData(hWndT, 0, hWnd);
  ListBox_SetCurSel(hWndT, 0);
  g_hWndNotepad := FindWindow('Notepad', nil);
  WalkWindowTree(hWndT, g_hWndNotepad);

  Result := TRUE;
end;

  // WM_DESTROY
procedure Dlg_OnDestroy(hWnd: HWND);
begin
  if (g_uTimerId <> 0) then KillTimer(hWnd, g_uTimerId);
end;

  // WM_COMMAND
procedure Dlg_OnCommand(hWnd: HWND; id: Integer; hWndCtl: HWND; codeNotify: UINT);
var
  hWndT: DWORD; // HWND
  Rc: TRect;
begin
  case (id) of
    IDCANCEL: // 关闭程序
      begin
        EndDialog(hWnd, 0);
      end;

    IDC_FUNCSTART: // 执行动作
      begin
        // 执行时间
        g_dwEventTime := GetTickCount() + 1000 * GetDlgItemInt(hWnd, IDC_DELAY, PBOOL(nil)^, FALSE);

        // 动作对象
        hWndT := GetDlgItem(hWnd, IDC_WNDS);
        g_hWndSubject := ListBox_GetItemData(hWndT, ListBox_GetCurSel(hWndT));

        // 动作编号
        g_nEventId := ComboBox_GetCurSel(GetDlgItem(hWnd, IDC_WNDFUNC));

        // 正要处理
        SetWindowText(GetDlgItem(hWnd, IDC_EVENTPENDING), 'Pending');
      end;

    IDC_THREADATTACH: // 共享输入
      begin
        AttachThreadInput(GetWindowThreadProcessId(g_hWndNotepad, nil), GetCurrentThreadId(), TRUE);
      end;

    IDC_THREADDETACH: // 取消共享
      begin
        AttachThreadInput(GetWindowThreadProcessId(g_hWndNotepad, nil), GetCurrentThreadId(), FALSE);
      end;

    IDC_SETCLIPRECT:  // 限制鼠标范围
      begin
        SetRect(rc, 0, 0, GetSystemMetrics(SM_CXSCREEN) div 2, GetSystemMetrics(SM_CYSCREEN) div 2);
        ClipCursor(@rc);
      end;

    IDC_REMOVECLIPRECT: // 取消限制
      begin
        ClipCursor(nil);
      end;

    IDC_HIDECURSOR: // 隐藏鼠标
      begin
        ShowCursor(FALSE);
      end;

    IDC_SHOWCURSOR: // 显示鼠标
      begin
        ShowCursor(TRUE);
      end;

    IDC_INFINITELOOP: // 死循环
      begin
        SetCursor(LoadCursor(0, IDC_NO));
        repeat Sleep(1) until FALSE;
      end;
  end;
end;

  // 强行向ListBox追加字符串
procedure AddStr(hWndLB: HWND; const szBuf: PChar);
var
  nIndex: Integer;
begin
  repeat
    nIndex := ListBox_AddString(hWndLB, szBuf);
    if (nIndex = LB_ERR) then ListBox_DeleteString(hWndLB, 0) else Break;
  until FALSE;

  ListBox_SetCurSel(hWndLB, nIndex);
end;

  // WM_RBUTTONDOWN & WM_RBUTTONDBLCLK
function Dlg_OnRButtonDown(hWnd: HWND; fDoubleClick: BOOL; x, y: Integer; keyFlags: UINT): Integer;
var
  szBuf: array[0..100] of Char;
begin
  _wvsprintf(szBuf, 'Capture=%-3s, Msg=RButtonDown, DblClk=%-3s, x=%5d, y=%5d',
    [ DWORD(IfThen(GetCapture() = 0, 'No', 'Yes')), DWORD(IfThen(fDoubleClick, 'Yes', 'No')), x, y ]);
    
  AddStr(GetDlgItem(hWnd, IDC_MOUSEMSGS), szBuf);

  if (fDoubleClick = FALSE) then SetCapture(hWnd) else ReleaseCapture();

  Result := 0;
end;

  // WM_RBUTTONUP
function Dlg_OnRButtonUp(hWnd: HWND; x, y: Integer; keyFlags: UINT): Integer;
var
  szBuf: array[0..100] of Char;
begin
  _wvsprintf(szBuf, 'Capture=%-3s, Msg=RButtonUp,   x=%5d, y=%5d',
    [ DWORD(IfThen(GetCapture() = 0, 'No', 'Yes')), x, y ]);

  AddStr(GetDlgItem(hWnd, IDC_MOUSEMSGS), szBuf);

  Result := 0;
end;

  // WM_LBUTTONDOWN & WM_LBUTTONDBLCLK
function Dlg_OnLButtonDown(hWnd: HWND; fDoubleClick: BOOL; x, y: Integer; keyFlags: UINT): Integer;
var
  szBuf: array[0..100] of Char;
begin
  _wvsprintf(szBuf, 'Capture=%-3s, Msg=LButtonDown, DblClk=%-3s, x=%5d, y=%5d',
    [ DWORD(IfThen(GetCapture() = 0, 'No', 'Yes')), DWORD(IfThen(fDoubleClick, 'Yes', 'No')), x, y ]);

  AddStr(GetDlgItem(hWnd, IDC_MOUSEMSGS), szBuf);

  Result := 0;
end;

  // WM_LBUTTONUP
procedure Dlg_OnLButtonUp(hWnd: HWND; x, y: Integer; keyFlags: UINT);
var
  szBuf: array[0..100] of Char;
begin
  _wvsprintf(szBuf, 'Capture=%-3s, Msg=LButtonUp,   x=%5d, y=%5d',
    [ DWORD(IfThen(GetCapture() = 0, 'No', 'Yes')), x, y ]);

  AddStr(GetDlgItem(hWnd, IDC_MOUSEMSGS), szBuf);
end;

  // WM_MOUSEMOVE
procedure Dlg_OnMouseMove(hWnd: HWND; x, y: Integer; keyFlags: UINT);
var
  szBuf: array[0..100] of Char;
begin
  _wvsprintf(szBuf, 'Capture=%-3s, Msg=MouseMove,  x=%5d, y=%5d',
    [ DWORD(IfThen(GetCapture() = 0, 'No', 'Yes')), x, y ]);

  AddStr(GetDlgItem(hWnd, IDC_MOUSEMSGS), szBuf);
end;

  // WM_TIMER
procedure Dlg_OnTimer(hWnd: HWND; id: UINT);
var
  szBuf: array[0..100] of Char;
  hWndT: DWORD; // HWND
  Rc: TRect;  
begin
  // 焦点控件
  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);
  _wvsprintf(szBuf, '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) or (GetTickCount() < g_dwEventTime) then Exit;

  // 动作编号
  case (g_nEventId) of
    0: g_hWndSubject := SetFocus(g_hWndSubject);

    1: g_hWndSubject := SetActiveWindow(g_hWndSubject);

    2: begin
         hWndT := GetForegroundWindow();
         SetForegroundWindow(g_hWndSubject);
         g_hWndSubject := hWndT;
       end;

    3: BringWindowToTop(g_hWndSubject);

    4: begin
         SetWindowPos(g_hWndSubject, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
         g_hWndSubject := 1;
       end;
       
    5: begin
         SetWindowPos(g_hWndSubject, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
         g_hWndSubject := 1;
       end;
  end;

  // 结果窗口
  if (g_hWndSubject = 1) then
    SetWindowText(GetDlgItem(hWnd, IDC_PREVWND), 'Can''t tell')
  else begin
    CalcWndText(g_hWndSubject, szBuf, chDIMOF(szBuf));
    SetWindowText(GetDlgItem(hWnd, IDC_PREVWND), szBuf);
  end;

  // 执行完毕
  g_hWndSubject := 0;
  g_nEventId := 0;
  g_dwEventTime := 0;
  SetWindowText(GetDlgItem(hWnd, IDC_EVENTPENDING), 'Executed');
end;

  // 对话框回调
function Dlg_Proc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM):BOOL; stdcall;
begin
  Result := TRUE;
  
  case (uMsg) of
    WM_INITDIALOG:
      Result := SetDlgMsgResult(hWnd, LRESULT(Dlg_OnInitDialog(hWnd, wParam, lParam)));

    WM_DESTROY:
      Dlg_OnDestroy(hWnd);

    WM_COMMAND:
      Dlg_OnCommand(hWnd, LOWORD(wParam), lParam, HIWORD(wParam));

    WM_MOUSEMOVE:
      Dlg_OnMouseMove(hWnd, LOWORD(lParam), HIWORD(lParam), wParam);

    WM_LBUTTONDOWN:
      Dlg_OnLButtonDown(hWnd, FALSE, LOWORD(lParam), HIWORD(lParam), wParam);

    WM_LBUTTONDBLCLK:
      Dlg_OnLButtonDown(hWnd, TRUE, LOWORD(lParam), HIWORD(lParam), wParam);

    WM_LBUTTONUP:
      Dlg_OnLButtonUp(hWnd, LOWORD(lParam), HIWORD(lParam), wParam);

    WM_RBUTTONDOWN:
      Dlg_OnRButtonDown(hWnd, FALSE, LOWORD(lParam), HIWORD(lParam), wParam);

    WM_RBUTTONDBLCLK:
      Dlg_OnRButtonDown(hWnd, TRUE, LOWORD(lParam), HIWORD(lParam), wParam);

    WM_RBUTTONUP:
      Dlg_OnRButtonUp(hWnd, LOWORD(lParam), HIWORD(lParam), wParam);

    WM_TIMER:
      Dlg_OnTimer(hWnd, wParam);

    else Result := FALSE;
  end;
end;

  // 程序入口
begin
  chWARNIFUNICODEUNDERWIN95();
  DialogBox(HInstance, MakeIntResource(IDD_LISLAB), 0, @Dlg_Proc);
end.

⌨️ 快捷键说明

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