Delphi 개발 DLL의 창 단추 표시 상태가 갱신되지 않는 문제를 해결합니다.

7988 단어 Delphi
DLL에 메시지 순환이 없기 때문에 DLL의 창에 TSpeedButton 컨트롤을 놓고 Flat 속성을 True로 설정합니다.운행하다.TspeedButton에서 마우스를 옮길 때 TspeedButton은 아무리 해도 복원할 수 없습니다.
다음과 같이 수동으로 메시지 처리를 받아야 합니다.
1. 창에 Timer1 구성 요소를 설치합니다. 2.간격은 1 3.Timer1Timer 이벤트에 코드 한 줄 쓰기:Application.HandleMessage;
 
내 창 전체 코드를 첨부합니다:
unit untBaseForm;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, Buttons, sSpeedButton, ImgList, StdCtrls, ExtCtrls, IniFiles,
   sLabel, untDefine, sSkinManager;

type
   TNowDataUser = record
      UserName:String; {    }
      UserCode:String; {    }
      UserPass:string; {    }
      UserFlag:Integer;{    }
   end;

   {    }
   TNowData = record
      User: TNowDataUser; {    }
      {...}
   end;
   TBaseForm = class(TForm)
      pnlBody: TPanel;
      pnlTitle: TPanel;
      btnwsClose: TsSpeedButton;
      btnwsMin: TsSpeedButton;
      btnwsMax: TsSpeedButton;
      btnwsNormal: TsSpeedButton;
      btnSkin: TsSpeedButton;
      btnMenu: TsSpeedButton;
      lblTitle: TsLabel;
      sm: TsSkinManager;
      procedure btnwsCloseClick(Sender: TObject);
      procedure btnwsMaxClick(Sender: TObject);
      procedure btnwsMinClick(Sender: TObject);
      procedure pnlTitleMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
      procedure FormShow(Sender: TObject);
      procedure btnSkinClick(Sender: TObject);
      procedure FormActivate(Sender: TObject);
      procedure FormCreate(Sender: TObject);
   private
      { Private declarations }
      FDefaultMaxWindows: boolean;
      FShowInTaskbar: Boolean;
      FShowDll: TTimer; {    Dll                     }
      procedure FShowDllTimer(Sender: TObject);
      procedure CreateParams(var Params: TCreateParams); override;
   protected
      procedure ini_SkinRead; virtual;
      procedure ini_SkinWrite(i: Integer); virtual;
      procedure SetwsMaxorNormal; virtual;
   public
      { Public declarations }
      NowData:TNowData; {    ,           ..}
      /// 
      ///              
      /// 
      /// 
      /// True:      (  Exe    )
      ///            ( :             ,    WindowState   ,        )
      constructor CreateSTB(AOwner: TComponent; ShowTaskbar: Boolean = False;DefaultMaxWindows:Boolean=False); virtual;
   published

   end;

var
   BaseForm: TBaseForm;

implementation

{$R *.dfm}

{  }
procedure TBaseForm.btnwsCloseClick(Sender: TObject);
begin
   Close;
end;

{   }
procedure TBaseForm.btnwsMaxClick(Sender: TObject);
begin
   if (btnwsNormal.Visible = false) and (btnwsMax.Visible = False) then exit;
   if WindowState = wsNormal then
   begin
      WindowState := wsMaximized;
      SetwsMaxorNormal;
   end
   else
   begin
      WindowState := wsNormal;
      Self.Left := (Screen.Width div 2) - (Self.Width div 2);
      Self.Top := (Screen.Height div 2) - (Self.Height div 2);
      SetwsMaxorNormal;
   end;
end;

{   }
procedure TBaseForm.btnwsMinClick(Sender: TObject);
begin
   //Application.Minimize;
   WindowState := wsMinimized;
end;

{    ,    }
procedure TBaseForm.pnlTitleMouseMove(Sender: TObject;
   Shift: TShiftState; X, Y: Integer);
begin
   if WindowState = wsMaximized then exit;
   if ssleft in Shift then ReleaseCapture;
   Perform(WM_SYSCOMMAND, $F012, 0);
end;

{      }
procedure TBaseForm.btnSkinClick(Sender: TObject);
begin
   ini_SkinWrite(pnlTitle.Tag + 1);
   ini_SkinRead;
end;

procedure TBaseForm.FormShow(Sender: TObject);
begin
   SetwsMaxorNormal;
   ini_SkinRead;
   Caption := lblTitle.Caption;

   {  Dll                     }
   if  Application.MainForm=nil  then
   begin
      if not (fsModal in Self.FormState) then
      begin
         if FShowDll=nil then
         begin
            FShowDll:= TTimer.Create(Self);
            FShowDll.Enabled:=False;
            FShowDll.Interval:=1;
            FShowDll.OnTimer:= FShowDllTimer;
         end;
         if not FShowDll.Enabled then FShowDll.Enabled:=true;
      end;
   end;
end;

{            }
procedure TBaseForm.SetwsMaxorNormal;
begin
   if (btnwsNormal.Visible = false) and (btnwsMax.Visible = False) then exit;
   btnwsMax.Visible := WindowState = wsNormal;
   btnwsNormal.Visible := WindowState = wsMaximized;
   btnwsNormal.Left := btnwsMax.Left;
   btnwsNormal.Top := btnwsMax.Top;
end;

{      }
procedure TBaseForm.ini_SkinRead;
var
   ini: TIniFile;
   i: integer;
begin
   ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'skin.dat');
   try
      pnlTitle.Tag := ini.ReadInteger('skin', 'color', 0);
      if pnlTitle.Tag > High(G_FormSkinColor) then pnlTitle.Tag := 0;
   finally
      FreeAndNil(ini);
   end;
   pnlTitle.Color := G_FormSkinColor[pnlTitle.Tag];
   pnlTitle.Refresh;

   for i := 0 to pnlTitle.ControlCount - 1 do
   begin
      if pnlTitle.Controls[i].Visible then
      begin
         pnlTitle.Controls[i].Hide;
         pnlTitle.Controls[i].Show;
      end;
   end;
end;

{      }
procedure TBaseForm.ini_SkinWrite(i: Integer);
var
   ini: TIniFile;
begin
   if i > High(G_FormSkinColor) then i := 0;
   ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'skin.dat');
   try
      ini.WriteInteger('skin', 'color', i);
   finally
      FreeAndNil(ini);
   end;
end;

procedure TBaseForm.CreateParams(var Params: TCreateParams);
begin
   inherited;
   if FShowInTaskbar then Params.WndParent := 0; //        
end;

constructor TBaseForm.CreateSTB(AOwner: TComponent; ShowTaskbar: Boolean = False;DefaultMaxWindows:Boolean=False);
begin
   if (ShowTaskbar)  and (Application.MainForm<>nil) then FShowInTaskbar := True;
   FDefaultMaxWindows:=DefaultMaxWindows;
   inherited Create(AOwner);
   //if not ShowTaskbar then SetWindowLong(Self.Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
end;

procedure TBaseForm.FormCreate(Sender: TObject);
begin
   if (WindowState = wsMaximized) or (FDefaultMaxWindows=True) then
   begin
      FDefaultMaxWindows := true;
      WindowState := wsNormal;
      Position := poDefault;
   end;
end;

procedure TBaseForm.FormActivate(Sender: TObject);
begin
   if FDefaultMaxWindows then
   begin
      WindowState := wsMaximized;
      FDefaultMaxWindows := false;
   end;
end;

procedure TBaseForm.FShowDllTimer(Sender: TObject);
begin
   if (Self<>nil ) and (Self.Visible) then
      Application.HandleMessage;
end;

end.

DLL 프로젝트 파일:
library Sale;

uses
  SysUtils,
  Classes,
  Forms,
  Controls,
  Windows,
  untBaseDM in '..\Common\untBaseDM.pas' {BaseDM: TDataModule},
  untBaseForm in '..\Common\untBaseForm.pas' {BaseForm},
  untSaleDemo in 'untSaleDemo.pas' {fmSaleDemo},
  untDM in 'untDM.pas' {DM: TDataModule};

{$R *.res}

/// 
///   fmSaleDemo
/// 
///         (True    ShowModal  )
///       
///        
///     
/// Application.Handle
/// fmSaleDemo
function GetFormSaleDemo(Taskbar: Boolean; New: Boolean; MaxWindows:Boolean; NowData:TNowData; AHandle: Thandle=0): TBaseForm; stdcall;
begin
   if Taskbar=False then Application.Handle:= AHandle;
   if (New) and (fmSaleDemo <> nil) then FreeAndNil(fmSaleDemo);
   if fmSaleDemo = nil then fmSaleDemo := TfmSaleDemo.CreateSTB(nil, Taskbar, MaxWindows);
   fmSaleDemo.NowData:=NowData;
   Result := fmSaleDemo;
end;

exports
   GetFormSaleDemo;



begin
end.

 
 
주 프로그램 호출:
 
function GetFormSaleDemo(Taskbar: Boolean; New: Boolean; MaxWindows: Boolean; NowData: TNowData; AHandle: Thandle = 0): TBaseForm; stdcall; external 'Sale.dll';

procedure TfmMain.btnSaleOrderClick(Sender: TObject);
var
   frm:TBaseForm;
begin
   frm := GetFormSaleDemo(False, True, False, NowData, Application.Handle);
   frm.ShowModal
end;

좋은 웹페이지 즐겨찾기