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

📄 echo.dpr

📁 这一系列是我平时收集的pascal深入核心编程
💻 DPR
字号:
program Echo;

{$R Echo.res}

uses Windows, Messages, Recorder in 'Recorder.pas';

const
 // 模板资源ID
  IDD_ECHO = 101;

 // 图标资源ID
  IDI_ECHO = 102;

 // 按钮控件ID
  IDC_RECORD = 1000;
  IDC_PLAY = 1001;
  IDC_STOP = 1002;

 // Purpose: 自定义(记录/回放)停止通知消息
 // wParam: hEventList - 事件列表句柄(仅当记录停止时有效)
 // lParam: TRecErr - 记录器错误类型(表示由于什么错误停止)
 // Return: 略
  UM_STOP = (WM_APP + 0);

 // 读取事件列表句柄(实际上是指针)
function GetEventList(hWnd: HWND): hEventList;
begin
  Result := GetWindowLong(hWnd, GWL_USERDATA);
end;

 // 保存事件列表句柄(实际上是指针)
procedure SetEventList(hWnd: HWND; h: hEventList);
begin
  SetWindowLong(hWnd, GWL_USERDATA, h);
end;

 // (根据当前记录器状态)设置按钮
procedure Echo_UpdateButtons(hWnd: HWND);
var
  RecMode: TRecMode;
  fRec, fPlay, fStop: BOOL;
  hWndRec, hWndPlay, hWndStop, hWndFocus: LongWord; // HWND
begin
 // 记录器状态
  RecMode := Recorder_GetMode();

 // 启用/禁用
  fRec := (RecMode = RECMODE_STOPPED);
  fPlay := (RecMode = RECMODE_STOPPED) and (GetEventList(hWnd) <> 0);
  fStop := (RecMode <> RECMODE_STOPPED);

 // 按钮句柄
  hWndRec := GetDlgItem(hWnd, IDC_RECORD);
  hWndPlay := GetDlgItem(hWnd, IDC_PLAY);
  hWndStop := GetDlgItem(hWnd, IDC_STOP);

 // 设置按钮
  EnableWindow(hWndRec, fRec);
  EnableWindow(hWndPlay, fPlay);
  EnableWindow(hWndStop, fStop);

 // 焦点按钮
  if fPlay then
    hWndFocus := hWndPlay
  else begin
    if fStop then
      hWndFocus := hWndStop
    else
      hWndFocus := hWndRec;
  end;

 // 设置焦点 
  SendMessage(hWnd, DM_SETDEFID, GetDlgCtrlID(hWndFocus), 0);
  SetFocus(hWndFocus);
end;

 // 对话框WM_INITDIALOG处理
function Echo_OnInitDialog(hWnd, hWndFocus: HWND; lParam: LPARAM): BOOL;
begin
 // 设置窗体图标
  SendMessage(hWnd, WM_SETICON, ICON_BIG, LoadIcon(HInstance, MakeIntResource(IDI_ECHO)));

 // 记录列表为空
  SetEventList(hWnd, 0);

 // 记录器初始化
  Recorder_Init();

 // 初始化各按钮
  Echo_UpdateButtons(hWnd);

 // 接受默认焦点
  Result := TRUE;
end;

 // 对话框UM_STOP处理
procedure Echo_OnStop(hWnd: HWND; h: hEventList; e: TRecErr);
begin
 // 本函数会因为记录/回放停止而调用,
 // h非空则为前者,需要保存,以便回放
  if (h <> 0) then SetEventList(hWnd, h);
  
  Echo_UpdateButtons(hWnd);
  Recorder_DisplayError(e);
end;

 // 对话框WM_COMMAND处理
procedure Echo_OnCommand(hWnd: HWND; id: Integer; hWndCtl: HWND; codeNotify: UINT);
var
  e: TRecErr;
begin
  case (id) of
    IDCANCEL: // 关闭对话框
      begin
       // 释放事件列表
        Recorder_Free(GetEventList(hWnd));

       // 结束消息循环
        PostQuitMessage(0);
      end;

    IDC_RECORD: // 选择'记录'
      begin
       // 释放事件列表
        if (GetEventList(hWnd) <> 0) then
        begin
          Recorder_Free(GetEventList(hWnd));
          SetEventList(hWnd, 0);
        end;

       // 安装记录钩子
        e := Recorder_Record(hWnd, UM_STOP);

        Echo_UpdateButtons(hWnd);
        Recorder_DisplayError(e);
      end;

    IDC_PLAY: // 选择'回放'
      begin
       // 安装回放钩子
        e := Recorder_Play(GetEventList(hWnd), hWnd, UM_STOP);
        
        Echo_UpdateButtons(hWnd);
        Recorder_DisplayError(e);
      end;

    IDC_STOP: // 选择'停止'
      begin
       // 停止记录or回放
        e := Recorder_Stop();
        
        Echo_UpdateButtons(hWnd);
        Recorder_DisplayError(e);
      end;
  end;
end;

 // 对话框消息处理回调
function Echo_DlgProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;
begin
  case (uMsg) of
    WM_INITDIALOG:
      begin
        Result := BOOL(SetWindowLong(hWnd, DWL_MSGRESULT,
          Longint(Echo_OnInitDialog(hWnd, wParam, lParam))));
      end;

    WM_COMMAND:
      begin
        Echo_OnCommand(hWnd, LOWORD(wParam), lParam, HIWORD(wParam));
        Result := TRUE;
      end;

    UM_STOP:
      begin
        Echo_OnStop(hWnd, wParam, TRecErr(lParam));
        Result := TRUE;
      end;

    else Result := FALSE;
  end;
end;

 // 程序'主线程'入口
var
  Msg: TMsg;
  hWnd: LongWord; // HWND
begin
 // 建立一个非模态对话框, 自己处理消息循环, 得以拦截WM_CANCELJOURNAL消息
  hWnd := CreateDialog(HInstance, MakeIntResource(IDD_ECHO), 0, @Echo_DlgProc);

 // 继续循环直至取出WM_QUIT消息
  while GetMessage(Msg, 0, 0, 0) do
  begin
   // 如果是WM_CANCELJOURNAL消息, 说明钩子已经因用户按下系统快捷键而失效
    Recorder_IsRecorderCanceled(@Msg);

   // 调用IsDialogMessage()分发消息, 它会对键盘消息作对话框式的特殊处理
    if (not IsDialogMessage(hWnd, Msg)) then
    begin
     // 不是对话框消息, 则作普通的分发和翻译
      TranslateMessage(Msg);
      DispatchMessage(Msg);
    end;
  end;

 // 因PostQuitMessage()而间接跳出消息循环, 清除作为主窗口的非模态对话框
  DestroyWindow(hWnd);
end.

⌨️ 快捷键说明

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