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.