unit main;
interface
uses
Messages, Windows, Forms, SysUtils, functionlibrary.Classes;
type
TOperaRunner = class
private
FDesktopWorkArea: TRect;
FOperaArea: LongWord;
FOperaHandle: THandle;
Flog: TLogWriter; // 可去掉不用[unctionlibrary.Classes.pas]
FCommand: string;
function GetDesktopWorkArea: Boolean;
procedure MakeWorkArea;
function GetOperaHandle: THandle;
procedure RunOpera;
procedure SetStyleAndRgn;
public
constructor create( const Cmd: string = ' Unknow ' );
destructor Destroy;override;
procedure doRun;
property Command: string read FCommand write FCommand;
end ;
implementation
const
OffsetXY = 4 ;
OffsetRB = 8 ;
{ TOperaRunner }
constructor TOperaRunner.create( const Cmd: string);
begin
FCommand : = Cmd;
Flog : = TLogWriter.Crate( ' .\log.txt ' );
Flog.Enable: = False;
end ;
destructor TOperaRunner.Destroy;
begin
Flog.Free;
inherited;
end ;
procedure TOperaRunner.doRun;
begin
if not GetDesktopWorkArea then
Exit;
MakeWorkArea;
if FCommand = ' Unknow ' then
RunOpera;
FOperaHandle : = GetOperaHandle;
SetStyleAndRgn;
end ;
// 下面为取桌面可用区域大小,只针对任务栏在底部的情况
function TOperaRunner.GetDesktopWorkArea: Boolean;
const
taskbarCls: PWideChar = ' Shell_TrayWnd ' ;
var
taskbarHandle: THandle;
taskbarRect: TRect;
begin
Result : = GetWindowRect(GetDesktopWindow, FDesktopWorkArea);
taskbarHandle : = FindWindow(taskbarCls, nil );
GetWindowRect(taskbarHandle, taskbarRect);
with taskbarRect do
begin
if Right > Bottom then // 任务栏在底部
begin
FDesktopWorkArea.Bottom : = taskbarRect.top + 8 ;
FDesktopWorkArea.Right : = FDesktopWorkArea.Right + 8 ;
end ;
end ;
with FDesktopWorkArea do
Flog.WriteFmt( ' Left=%d top=%d right=%d bottom=%d ' ,
[Left, top, Right, Bottom]);
// SystemParametersInfo(SPI_GETWORKAREA, 0 ,@FDesktopWorkArea, 0 );
end ;
// 使用枚举的方式判断opera的主窗体,若用findwindow则可能找不到
function TOperaRunner.GetOperaHandle: THandle;
var
ClsName: array [ 0 .. 255 ] of WideChar;
WndStyle: Integer;
OperaClassName: string;
const
operaClass: string = ' OpWindow ' ;
begin
Result : = GetWindow(Application.Handle, GW_HWNDFIRST);
while Result <> 0 do
begin
GetClassName(Result, ClsName, 255 );
OperaClassName : = ClsName;
if SameText(operaClass, OperaClassName) then
begin
WndStyle : = GetWindowLong(Result, GWL_STYLE);
if ((WndStyle and WS_MINIMIZEBOX) = WS_MINIMIZEBOX) and
((WndStyle and WS_MAXIMIZEBOX) = WS_MAXIMIZEBOX) and
((WndStyle and WS_OVERLAPPED) = WS_OVERLAPPED) then
begin
ShowWindow(Result, SW_SHOWNORMAL);
Break;
end ;
end ;
Result : = GetNextWindow(Result, GW_HWNDNEXT);
end ;
end ;
procedure TOperaRunner.MakeWorkArea;
begin
FOperaArea : = CreateRectRgnIndirect(FDesktopWorkArea);
OffsetRgn(FOperaArea, - 4 , - 4 );
end ;
procedure TOperaRunner.RunOpera;
const
OperaFile: string = ' %sopera.exe ' ;
var
s: AnsiString;
Folder: string;
begin
Folder : = ExtractFilePath(ParamStr( 0 ));
if Folder[Length(Folder)] <> ' \ ' then
Folder : = Folder + ' \ ' ;
s : = Format(OperaFile, [Folder]);
Flog.Write( ' opera= ' + s);
WinExec(PAnsiChar(s), SW_NORMAL);
end ;
procedure TOperaRunner.SetStyleAndRgn;
var
NewStyle: Integer;
begin
if FOperaHandle = 0 then
Exit;
Flog.Write( ' opera handle ' + inttohex(FOperaHandle, 8 ));
NewStyle : = GetWindowLong(FOperaHandle, GWL_STYLE) and ( not WS_CAPTION) and
( not WS_SYSMENU);
SetWindowLong(FOperaHandle, GWL_STYLE, NewStyle); // 去掉标题栏及系统菜单
SetWindowRgn(FOperaHandle, FOperaArea, True);
ShowWindowAsync(FOperaHandle, SW_MAX);
with FDesktopWorkArea do
MoveWindow(FOperaHandle, Left - OffsetXY, top - OffsetXY, Right - 1 , Bottom - 1 ,
True)
end ;
end .
interface
uses
Messages, Windows, Forms, SysUtils, functionlibrary.Classes;
type
TOperaRunner = class
private
FDesktopWorkArea: TRect;
FOperaArea: LongWord;
FOperaHandle: THandle;
Flog: TLogWriter; // 可去掉不用[unctionlibrary.Classes.pas]
FCommand: string;
function GetDesktopWorkArea: Boolean;
procedure MakeWorkArea;
function GetOperaHandle: THandle;
procedure RunOpera;
procedure SetStyleAndRgn;
public
constructor create( const Cmd: string = ' Unknow ' );
destructor Destroy;override;
procedure doRun;
property Command: string read FCommand write FCommand;
end ;
implementation
const
OffsetXY = 4 ;
OffsetRB = 8 ;
{ TOperaRunner }
constructor TOperaRunner.create( const Cmd: string);
begin
FCommand : = Cmd;
Flog : = TLogWriter.Crate( ' .\log.txt ' );
Flog.Enable: = False;
end ;
destructor TOperaRunner.Destroy;
begin
Flog.Free;
inherited;
end ;
procedure TOperaRunner.doRun;
begin
if not GetDesktopWorkArea then
Exit;
MakeWorkArea;
if FCommand = ' Unknow ' then
RunOpera;
FOperaHandle : = GetOperaHandle;
SetStyleAndRgn;
end ;
// 下面为取桌面可用区域大小,只针对任务栏在底部的情况
function TOperaRunner.GetDesktopWorkArea: Boolean;
const
taskbarCls: PWideChar = ' Shell_TrayWnd ' ;
var
taskbarHandle: THandle;
taskbarRect: TRect;
begin
Result : = GetWindowRect(GetDesktopWindow, FDesktopWorkArea);
taskbarHandle : = FindWindow(taskbarCls, nil );
GetWindowRect(taskbarHandle, taskbarRect);
with taskbarRect do
begin
if Right > Bottom then // 任务栏在底部
begin
FDesktopWorkArea.Bottom : = taskbarRect.top + 8 ;
FDesktopWorkArea.Right : = FDesktopWorkArea.Right + 8 ;
end ;
end ;
with FDesktopWorkArea do
Flog.WriteFmt( ' Left=%d top=%d right=%d bottom=%d ' ,
[Left, top, Right, Bottom]);
// SystemParametersInfo(SPI_GETWORKAREA, 0 ,@FDesktopWorkArea, 0 );
end ;
// 使用枚举的方式判断opera的主窗体,若用findwindow则可能找不到
function TOperaRunner.GetOperaHandle: THandle;
var
ClsName: array [ 0 .. 255 ] of WideChar;
WndStyle: Integer;
OperaClassName: string;
const
operaClass: string = ' OpWindow ' ;
begin
Result : = GetWindow(Application.Handle, GW_HWNDFIRST);
while Result <> 0 do
begin
GetClassName(Result, ClsName, 255 );
OperaClassName : = ClsName;
if SameText(operaClass, OperaClassName) then
begin
WndStyle : = GetWindowLong(Result, GWL_STYLE);
if ((WndStyle and WS_MINIMIZEBOX) = WS_MINIMIZEBOX) and
((WndStyle and WS_MAXIMIZEBOX) = WS_MAXIMIZEBOX) and
((WndStyle and WS_OVERLAPPED) = WS_OVERLAPPED) then
begin
ShowWindow(Result, SW_SHOWNORMAL);
Break;
end ;
end ;
Result : = GetNextWindow(Result, GW_HWNDNEXT);
end ;
end ;
procedure TOperaRunner.MakeWorkArea;
begin
FOperaArea : = CreateRectRgnIndirect(FDesktopWorkArea);
OffsetRgn(FOperaArea, - 4 , - 4 );
end ;
procedure TOperaRunner.RunOpera;
const
OperaFile: string = ' %sopera.exe ' ;
var
s: AnsiString;
Folder: string;
begin
Folder : = ExtractFilePath(ParamStr( 0 ));
if Folder[Length(Folder)] <> ' \ ' then
Folder : = Folder + ' \ ' ;
s : = Format(OperaFile, [Folder]);
Flog.Write( ' opera= ' + s);
WinExec(PAnsiChar(s), SW_NORMAL);
end ;
procedure TOperaRunner.SetStyleAndRgn;
var
NewStyle: Integer;
begin
if FOperaHandle = 0 then
Exit;
Flog.Write( ' opera handle ' + inttohex(FOperaHandle, 8 ));
NewStyle : = GetWindowLong(FOperaHandle, GWL_STYLE) and ( not WS_CAPTION) and
( not WS_SYSMENU);
SetWindowLong(FOperaHandle, GWL_STYLE, NewStyle); // 去掉标题栏及系统菜单
SetWindowRgn(FOperaHandle, FOperaArea, True);
ShowWindowAsync(FOperaHandle, SW_MAX);
with FDesktopWorkArea do
MoveWindow(FOperaHandle, Left - OffsetXY, top - OffsetXY, Right - 1 , Bottom - 1 ,
True)
end ;
end .