16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"RE^2:コモンダイアログの表示位置を変更"
この発言は #00491 Satobe さんのRE:コモンダイアログの表示位置を変更 に対するコメントです
◆解説
OnSetLeftTopイベントでパラメータの ALeft, Atopに表示したい
スクリーン座標を設定することで、自由に表示位置が制御できる
TMyOpenDialog コンポーネント版です。
◆実際のコード
----- ここから -----
unit MyOpenDialog;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TDialogSetLeftTopEvent = procedure(Sender: TObject;
var ALeft, ATop: Integer;
AWidth, AHeight: Integer) of object;
TMyOpenDialog = class(TOpenDialog)
private
FSubClassHandle: HWND;
FMoveFlag: Boolean;
FNewWndProc, FOldWndProc: TFarProc;
FOnSetLeftTop: TDialogSetLeftTopEvent;
procedure NewWndProc(var Message: TMessage);
protected
procedure DoClose; override;
procedure DoShow; override;
public
constructor Create(AOwner: TComponent); override;
published
property OnSetLeftTop: TDialogSetLeftTopEvent
read FOnSetLeftTop write FOnSetLeftTop;
end;
procedure Register;
implementation
constructor TMyOpenDialog.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FOnSetLeftTop := nil;
FSubClassHandle := HWND(nil);
FNewWndProc := nil;
FOldWndProc := nil;
end;
procedure TMyOpenDialog.DoClose;
begin
SetWindowLong(FSubClassHandle, GWL_WNDPROC,
Longint(FOldWndProc));
FreeObjectInstance(FNewWndProc);
FSubClassHandle := HWND(nil);
FNewWndProc := nil;
FOldWndProc := nil;
inherited DoClose;
end;
procedure TMyOpenDialog.DoShow;
var
ClassName: array[0..255] of Char;
begin
inherited DoShow;
FSubClassHandle := Handle;
if GetClassName(GetParent(FSubClassHandle),
ClassName, 255) > 0 then begin
if StrComp(ClassName, '#32770') = 0 then begin
FSubClassHandle := GetParent(FSubClassHandle);
end;
end;
FMoveFlag := True; //位置の移動が必要
FNewWndProc := MakeObjectInstance(NewWndProc);
FOldWndProc := Pointer(GetWindowLong(FSubClassHandle,
GWL_WNDPROC));
SetWindowLong(FSubClassHandle, GWL_WNDPROC,
Longint(FNewWndProc));
end;
procedure TMyOpenDialog.NewWndProc(var Message: TMessage);
var
pWinPos: PWindowPos;
rc: TRect;
ALeft, ATop: Integer;
begin
if (Message.Msg = WM_WINDOWPOSCHANGING) and FMoveFlag then begin
FMoveFlag := False; //位置調整を行った
if Assigned(FOnSetLeftTop) then begin
GetWindowRect(FSubClassHandle, rc);
pWinPos := PWindowPos(Message.LParam);
ALeft := pWinPos^.x;
ATop := pWinPos^.y;
FOnSetLeftTop(Self, ALeft, ATop,
rc.Right - rc.Left,
rc.Bottom - rc.Top);
pWinPos^.x := ALeft;
pWinPos^.y := ATop;
pWinPos^.flags := pWinPos^.flags and (not SWP_NOMOVE);
end;
end;
Message.Result := CallWindowProc(FOldWndProc,
FSubClassHandle,
Message.Msg,
Message.WParam,
Message.LParam);
end;
procedure Register;
begin
RegisterComponents('Samples', [TMyOpenDialog]);
end;
end.
----- ここまで -----
TCommonDialog から派生しているクラスなら、どれでも同様の
方法で、表示位置制御ができるはずです。
例えば TPrinterSetupDialog ならば、
> TMyOpenDialog = class(TOpenDialog)
ここを TMyPrinterSetupDialog = class(TPrinterSetupDialog)
に修正して、ソースコード中のすべての TMyOpenDialog を
TMyPrinterSetupDialog に修正してやればok(のはず)です。
99/09/24(金) 23:50 Satobe(JCG00336)
Original document by Satobe 氏 ID:(JCG00336)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|