DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: jeff1314
今日帖子: 6
在线用户: 4
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2020/3/26 3:28:37
标题:
Creating a "counter" to close your "Active window", like MessageDLG using SetTimer() and PostMessage 浏览:694
加入我的收藏
楼主: Creating a "counter" to close your "Active window", like MessageDLG using SetTimer() and PostMessage() from API Windows
Code by Žarko Gajić  (MVP Embarcadero)


unit uMainForm;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.Menus,
  Vcl.Buttons,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    Arquivo1: TMenuItem;
    Opc11: TMenuItem;
    Opc21: TMenuItem;
    Opc31: TMenuItem;
    N1: TMenuItem;
    Opc41: TMenuItem;
    Help1: TMenuItem;
    Opc12: TMenuItem;
    Opc22: TMenuItem;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  System.UITypes, // msg buttons
  Vcl.Consts;     // SMsgDlgInformation

//**********
// Code by Žarko Gajić  (MVP Embarcadero)
//**********

function MessageDlgTimed(const Msg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; HelpCtx: Longint; const closePeriod: integer = 2000): Integer;
var
  timerCloseId: UINT_PTR;

  procedure CloseMessageDlgCallback(AWnd: HWND; AMsg: UINT; AIDEvent: UINT_PTR; ATicks: DWORD); stdcall;
  var
    activeWnd: HWND;
  begin
    KillTimer(AWnd, AIDEvent);

    activeWnd := GetActiveWindow;

    if IsWindow(activeWnd) and IsWindowEnabled(activeWnd) then
      PostMessage(activeWnd, WM_CLOSE, 0, 0);
  end; (* CloseMessageDlgCallback *)

begin
  timerCloseId := SetTimer(0, 0, closePeriod, @CloseMessageDlgCallback);
  //
  result := MessageDlg(Msg + ', ' + closePeriod.ToString + 'ms to destroy itself', DlgType, Buttons, HelpCtx);
  //
  if timerCloseId <> 0 then
    KillTimer(0, timerCloseId);
end;

//**********
function HookResourceString(ResStringRec: pResStringRec; NewStr: pChar): integer;
var
  OldProtect: DWORD;
begin
  VirtualProtect(ResStringRec, SizeOf(ResStringRec^), PAGE_EXECUTE_READWRITE, @OldProtect);
  result          := ResStringRec^.Identifier;
  ResStringRec^.Identifier := Integer(NewStr);
  VirtualProtect(ResStringRec, SizeOf(ResStringRec^), OldProtect, @OldProtect);
end;

procedure UnHookResourceString(ResStringRec: pResStringRec; oldData: integer);
var
  OldProtect: DWORD;
begin
  VirtualProtect(ResStringRec, SizeOf(ResStringRec^), PAGE_EXECUTE_READWRITE, @OldProtect);
  ResStringRec^.Identifier := oldData;
  VirtualProtect(ResStringRec, SizeOf(ResStringRec^), OldProtect, @OldProtect);
end;

function MessageDlgTimedAdvanced(const Msg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; HelpCtx: Longint; const closePeriod: integer = 5000): Integer;
const
  tickPeriod = 250;
var
  timerCloseId, timerTickId: UINT_PTR;
  r          : integer;
  peekMsg          : TMsg;

  procedure CloseMessageDlgCallback(AWnd: HWND; AMsg: UINT; AIDEvent: UINT_PTR; ATicks: DWORD); stdcall;
  var
    activeWnd: HWND;
  begin
    KillTimer(AWnd, AIDEvent);

    activeWnd := GetActiveWindow;

    if IsWindow(activeWnd) and IsWindowEnabled(activeWnd) then
      PostMessage(activeWnd, WM_CLOSE, 0, 0);
  end; (* CloseMessageDlgCallback *)

  procedure PingMessageDlgCallback(AWnd: HWND; AMsg: UINT; AIDEvent: UINT_PTR; ATicks: DWORD); stdcall;
  var
    activeWnd     : HWND;
    wCaption      : string;
    wCaptionLength: integer;
  begin
    activeWnd := GetActiveWindow;
    if IsWindow(activeWnd) and IsWindowEnabled(activeWnd) and IsWindowVisible(activeWnd) then
    begin
      wCaptionLength := GetWindowTextLength(activeWnd);
      SetLength(wCaption, wCaptionLength);
      GetWindowText(activeWnd, PChar(wCaption), 1 + wCaptionLength);
      SetWindowText(activeWnd, Copy(wCaption, 1, -1 + Length(wCaption)));
    end
    else
      KillTimer(AWnd, AIDEvent);
  end; (* PingMessageDlgCallback *)

//
begin
  if (DlgType = mtInformation) and ([mbOK] = Buttons) then
  begin
    timerCloseId := SetTimer(0, 0, closePeriod, @CloseMessageDlgCallback);

    if timerCloseId <> 0 then
    begin
      timerTickId := SetTimer(0, 0, tickPeriod, @PingMessageDlgCallback);

      if timerTickId <> 0 then
        r := HookResourceString(@SMsgDlgInformation, PChar(SMsgDlgInformation + ' ' + StringOfChar('.', closePeriod div tickPeriod)));
    end;

    result := MessageDlg(Msg, DlgType, Buttons, HelpCtx);

    if timerTickId <> 0 then
    begin
      KillTimer(0, timerTickId);
      UnHookResourceString(@SMsgDlgInformation, r);
    end;

    if timerCloseId <> 0 then
      KillTimer(0, timerCloseId);
  end
  else
    result := MessageDlg(Msg, DlgType, Buttons, HelpCtx);
end;

//**********
procedure TForm1.Button2Click(Sender: TObject);
begin
  MessageDlgTimedAdvanced('string', mtInformation, [mbOK], 0, 5000); // ok
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MessageDlgTimed('string', mtInformation, [mbYes], 0, 4000); // ok
end;

end.
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2020/3/26 3:29:19
1楼: screenshot
此帖子包含附件:
PNG 图像
大小:107.8K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行131.8359毫秒 RSS