Delphi 分割系统桌面屏幕的显示区域?(100分悬赏!!!)

springcyq 2008-08-28 01:27:35
如何让桌面上所有的窗体最大化时的顶端(y值)都在指定的高度,而不是屏幕的最上端(即y=0)?即实现MyTest和系统桌面进行分割屏幕的显示区域?(100分悬赏!!!)

我想实现如下的编程:

程序MyTest启动后界面是一长条状的窗体,就像桌面下端任务栏一样,只不过它是总居于屏幕上端,当你打开其他任何窗体或应用程序时,所有窗体最大化时的顶端(y值)都在MyTest下面,就像任务栏总居下端一样,MyTest它是总居上端。其中桌面的最上端也在MyTest下端。
请问如何编程实现,其编程的思路是什么?

要求:Delphi代码或控件

如果我想让MyTest总居屏幕左边、右边和下边呢?换一种说法,就是我如何实现MyAPP和系统桌面进行分割屏幕的显示区域?(请参考WinME&Win2000开始菜单>>附件>>辅助工具>>放大程序,就是我想编程实现的这种示例。)
请高手指教,谢绝灌水。如哪位有好的源码,我将再加分奉送!
My E-Mail: Leaf_Zhang@pegatroncorp.com

其实,http://topic.csdn.net/t/20010424/17/104419.html
就有这个提问,不过,答案是VB的,我看不明白。
答案:http://www.applevb.com/sourcecode/dockbarapp.zip


谢谢先!
...全文
702 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
springcyq 2008-09-23
  • 打赏
  • 举报
回复
谢谢各位的热心帮助!!感谢!

最近超忙的说,楼上的两个方法都没有来得及试呢。
希望国庆期间有时间验证下,不然,实在愧对大家的热心协助。

再次感谢……
springcyq 2008-09-23
  • 打赏
  • 举报
回复
谢谢各位的热心帮助!!感谢!

最近超忙的说,楼上的两个方法都没有来得及试呢。
希望国庆期间有时间验证下,不然,实在愧对大家的热心协助。

再次感谢……
qian_longN1 2008-09-22
  • 打赏
  • 举报
回复
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
private
procedure WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1 : TForm1;

implementation
procedure TForm1.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);
begin
with Message.MinMaxInfo^ do
begin
ptMaxSize.X := 1000; {最大化时宽度}
ptMaxSize.Y := 1000; {最大化时高度}
ptMaxPosition.X := 10; {最大化时左上角横坐标}
ptMaxPosition.Y := 10; {最大化时左上角纵坐标}
end;
Message.Result := 0; {告诉Windows你改变了 minmaxinfo}
inherited;
end;

{$R *.dfm}

end.


完整代码!!!希望是你需要地
qian_longN1 2008-09-22
  • 打赏
  • 举报
回复
procedure TForm1.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);
begin
with Message.MinMaxInfo^ do
begin
ptMaxSize.X := 1000; {最大化时宽度}
ptMaxSize.Y := 1000; {最大化时高度}
ptMaxPosition.X := 10; {最大化时左上角横坐标}
ptMaxPosition.Y := 10; {最大化时左上角纵坐标}
end;
Message.Result := 0; {告诉Windows你改变了 minmaxinfo}
inherited;
end;


不知道是不是这个
okmnji79513 2008-09-22
  • 打赏
  • 举报
回复
关注 帮顶
ahjoe 2008-09-15
  • 打赏
  • 举报
回复
别动不动就Hook!
suton 2008-09-11
  • 打赏
  • 举报
回复
那个是需要做dll的
springcyq 2008-09-11
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 suiyunonghen 的回复:]
没有那么复杂
就在MyTest程序中搞个Hook,让他来Hook WM_GETMINMAXINFO消息,这样自己处理就行了,可以针对所有窗口
[/Quote]

请问大哥有具体的例子么?谢谢~
Hook……我不会……
springcyq 2008-09-11
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 suiyunonghen 的回复:]
没有那么复杂
就在MyTest程序中搞个Hook,让他来Hook WM_GETMINMAXINFO消息,这样自己处理就行了,可以针对所有窗口
[/Quote]

请问大哥有具体的例子么?谢谢~
Hook……我不会……
springcyq 2008-09-11
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 suiyunonghen 的回复:]
没有那么复杂
就在MyTest程序中搞个Hook,让他来Hook WM_GETMINMAXINFO消息,这样自己处理就行了,可以针对所有窗口
[/Quote]

请问大哥有具体的例子么?谢谢~
Hook……我不会……
不得闲 2008-09-09
  • 打赏
  • 举报
回复
没有那么复杂
就在MyTest程序中搞个Hook,让他来Hook WM_GETMINMAXINFO消息,这样自己处理就行了,可以针对所有窗口
springcyq 2008-09-08
  • 打赏
  • 举报
回复
首先感谢 9 楼 suton 大哥的热心援助!!谢谢!!!

我还要验证下,如果能正确实现(分割系统桌面屏幕的显示区域)的话,我会结帖的。
如果有其他相关问题,我会另外发帖提问。

这个 CASE 我已经delay一个月了……呜呜呜……
suton 2008-09-05
  • 打赏
  • 举报
回复
终于找到对应的API了:
SHAppBarMessage Function

--------------------------------------------------------------------------------

Sends an appbar message to the system.

Syntax

UINT_PTR SHAppBarMessage( DWORD dwMessage,
PAPPBARDATA pData
);
Parameters

dwMessage
Appbar message value to send. This parameter can be one of the following values:
ABM_ACTIVATE
Notifies the system that an appbar has been activated.
ABM_GETAUTOHIDEBAR
Retrieves the handle to the autohide appbar associated with a particular edge of the screen.
ABM_GETSTATE
Retrieves the autohide and always-on-top states of the Microsoft® Windows® taskbar.
ABM_GETTASKBARPOS
Retrieves the bounding rectangle of the Windows taskbar.
ABM_NEW
Registers a new appbar and specifies the message identifier that the system should use to send notification messages to the appbar.
ABM_QUERYPOS
Requests a size and screen position for an appbar.
ABM_REMOVE
Unregisters an appbar, removing the bar from the system's internal list.
ABM_SETAUTOHIDEBAR
Registers or unregisters an autohide appbar for an edge of the screen.
ABM_SETPOS
Sets the size and screen position of an appbar.
ABM_SETSTATE
Sets the state of the appbar's autohide and always-on-top attributes.
ABM_WINDOWPOSCHANGED
Notifies the system when an appbar's position has changed.
pData
Address of an APPBARDATA structure. The content of the structure depends on the value set in the dwMessage parameter.
Return Value

Returns a message-dependent value. For more information, see the Microsoft Platform Software Development Kit (SDK) documentation for the appbar message sent.
suton 2008-09-05
  • 打赏
  • 举报
回复
搜了一下,delphi也有控件:
http://www.delphifans.com/SoftView/SoftView_905.html
不过没源码
suton 2008-09-05
  • 打赏
  • 举报
回复
SystemParametersInfo这个API不知道能不能实现你的要求.
原型:
BOOL SystemParametersInfo(
UINT uiAction,
UINT uiParam,
PVOID pvParam,
UINT fWinIni
);
给uiAction传入参数: SPI_SETWORKAREA 设置桌面工作区域 (你可以查查MSDN)
设置前,先用SPI_GETWORKAREA取得工作区域范围,保存起来,程序退出的时候,再设置回来.

但是问题是,这样一来,你自己本身的这个MyTest程序,估计也会显示在设置后的workarea里面了.而不是外面的区域.
按照这种思路来做的话,问题变成:如何将程序显示在非WORK AREA的地方.
suton 2008-09-05
  • 打赏
  • 举报
回复
拦截WM_GETMINMAXINFO只能实现当前delphi程序最大化后的大小和位置.不能对所有新打开的其他程序有效.

你的这个需求,需要用到windows API来实现,但是什么API可以实现它,现在我还不知道.
suton 2008-09-05
  • 打赏
  • 举报
回复
procedure TAppBar.Top1Click(Sender: TObject);
begin
FLastChecked.Checked := False;
(Sender as TMenuItem).Checked := True;
case TMenuItem(Sender).Caption[2] of
'T': Edge := abeTop;
'B': Edge := abeBottom;
'L': Edge := abeLeft;
'R': Edge := abeRight;
end;
FLastChecked := TMenuItem(Sender);
end;

procedure TAppBar.MoveButtons;
// This method looks complicated, but it really just arranges the buttons
// properly depending on what side the AppBar is docked.
var
DeltaCenter, NewPos: Integer;
begin
if (FEdge = abeTop) or (FEdge = abeBottom) then
begin
DeltaCenter := (ClientHeight - SpeedButton1.Height) div 2;
SpeedButton1.SetBounds(10, DeltaCenter, SpeedButton1.Width, SpeedButton1.Height);
NewPos := SpeedButton1.Width + 20;
SpeedButton2.SetBounds(NewPos, DeltaCenter, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Width + 10;
SpeedButton3.SetBounds(NewPos, DeltaCenter, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Width + 10;
SpeedButton4.SetBounds(NewPos, DeltaCenter, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Width + 10;
SpeedButton5.SetBounds(NewPos, DeltaCenter, SpeedButton1.Width, SpeedButton1.Height);
end;
if (FEdge = abeLeft) or (FEdge = abeRight) then
begin
DeltaCenter := (ClientWidth - SpeedButton1.Width) div 2;
SpeedButton1.SetBounds(DeltaCenter, 10, SpeedButton1.Width, SpeedButton1.Height);
NewPos := SpeedButton1.Height + 20;
SpeedButton2.SetBounds(DeltaCenter, NewPos, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Height + 10;
SpeedButton3.SetBounds(DeltaCenter, NewPos, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Height + 10;
SpeedButton4.SetBounds(DeltaCenter, NewPos, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Height + 10;
SpeedButton5.SetBounds(DeltaCenter, NewPos, SpeedButton1.Width, SpeedButton1.Height);
end;
end;

procedure TAppBar.SpeedButton1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
MainForm.FileName := OpenDialog1.FileName;
end;

procedure TAppBar.SpeedButton2Click(Sender: TObject);
begin
MainForm.memEditor.Lines.SaveToFile(MainForm.FileName);
end;

procedure TAppBar.SpeedButton3Click(Sender: TObject);
begin
MainForm.memEditor.CutToClipboard;
end;

procedure TAppBar.SpeedButton4Click(Sender: TObject);
begin
MainForm.memEditor.CopyToClipboard;
end;

procedure TAppBar.SpeedButton5Click(Sender: TObject);
begin
MainForm.memEditor.PasteFromClipboard;
end;

procedure TAppBar.Exit1Click(Sender: TObject);
begin
Application.Terminate;
end;

initialization
AppBarMsg := RegisterWindowMessage('DDG AppBar Message');
end.
suton 2008-09-05
  • 打赏
  • 举报
回复
procedure TAppBar.WndProc(var M: TMessage);
var
State: UINT;
begin
if M.Msg = AppBarMsg then
begin
case M.WParam of
// Sent when always on top or autohide state has changed.
ABN_STATECHANGE:
begin
// Check to see whether the access bar is still ABS_ALWAYSONTOP.
State := SendAppBarMsg(ABM_GETSTATE);
if ABS_ALWAYSONTOP and State = 0 then
SetTopMost(False)
else
SetTopMost(True);
end;
// A full screen application has started, or the last
// full-screen application has closed.
ABN_FULLSCREENAPP:
begin
// Set the access bar's z-order appropriately.
State := SendAppBarMsg(ABM_GETSTATE);
if M.lParam <> 0 then begin
if ABS_ALWAYSONTOP and State = 0 then
SetTopMost(False)
else
SetTopMost(True);
end
else
if State and ABS_ALWAYSONTOP <> 0 then
SetTopMost(True);
end;
// Sent when something happened which may effect the AppBar position.
ABN_POSCHANGED:
begin
// The taskbar or another access bar
// has changed its size or position.
SetAppBarPos(FABD.uEdge);
end;
end;
end
else
inherited WndProc(M);
end;

function TAppBar.SendAppBarMsg(Msg: DWORD): UINT;
begin
Result := SHAppBarMessage(Msg, FABD);
end;

procedure TAppBar.SetAppBarPos(Edge: UINT);
begin
FABD.uEdge := Edge; // set edage
with FABD.rc do
begin
// set coordinates to full-scren
Top := 0;
Left := 0;
Right := Screen.Width;
Bottom := Screen.Height;
// Send ABM_QUERYPOS to obtain proper rect on edge
SendAppBarMsg(ABM_QUERYPOS);
// re-adjust rect based on that modified by ABM_QUERYPOS
case Edge of
ABE_LEFT: Right := Left + DEF_APPBAR_WIDTH;
ABE_RIGHT: Left := Right - DEF_APPBAR_WIDTH;
ABE_TOP: Bottom := Top + DEF_APPBAR_HEIGHT;
ABE_BOTTOM: Top := Bottom - DEF_APPBAR_HEIGHT;
end;
// Set the app bar position.
SendAppBarMsg(ABM_SETPOS);
end;
// Set the BoundsRect property so that it conforms to the
// bounding rectangle passed to the system.
BoundsRect := FABD.rc;
end;

procedure TAppBar.SetTopMost(TopMost: Boolean);
const
WndPosArray: array[Boolean] of HWND = (HWND_BOTTOM, HWND_TOPMOST);
begin
SetWindowPos(Handle, WndPosArray[TopMost], 0, 0, 0, 0, SWP_NOMOVE or
SWP_NOSIZE or SWP_NOACTIVATE);
end;

procedure TAppBar.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
Params.Style := WS_VISIBLE or WS_POPUP or WS_THICKFRAME or WS_CLIPCHILDREN;
end;

procedure TAppBar.SetAppBarEdge(Value: TAppBarEdge);
const
EdgeArray: array[TAppBarEdge] of UINT = (ABE_TOP, ABE_BOTTOM, ABE_LEFT,
ABE_RIGHT);
begin
if Value <> FEdge then
begin
SetAppBarPos(EdgeArray[Value]);
FEdge := Value;
MoveButtons;
end;
end;

suton 2008-09-05
  • 打赏
  • 举报
回复
unit AppBars;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ShellAPI, StdCtrls, Buttons, ExtCtrls, Menus;

type
TAppBarEdge = (abeTop, abeBottom, abeLeft, abeRight);

EAppBarError = class(Exception);

TAppBar = class(TForm)
PopupMenu1: TPopupMenu;
Top1: TMenuItem;
Bottom1: TMenuItem;
Left1: TMenuItem;
Right1: TMenuItem;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
SpeedButton4: TSpeedButton;
SpeedButton5: TSpeedButton;
OpenDialog1: TOpenDialog;
N1: TMenuItem;
Exit1: TMenuItem;
procedure Top1Click(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure MoveButtons;
procedure SpeedButton2Click(Sender: TObject);
procedure SpeedButton4Click(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
procedure SpeedButton5Click(Sender: TObject);
procedure Exit1Click(Sender: TObject);
private
FABD: TAppBarData;
FEdge: TAppBarEdge;
FTopMost: Boolean;
FLastChecked: TMenuItem;
procedure WMActivate(var M: TMessage); message WM_ACTIVATE;
procedure WMWindowPosChanged(var M: TMessage); message WM_WINDOWPOSCHANGED;
function SendAppBarMsg(Msg: DWORD): UINT;
procedure SetAppBarPos(Edge: UINT);
procedure SetAppBarEdge(Value: TAppBarEdge);
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure SetTopMost(TopMost: Boolean);
procedure WndProc(var M: TMessage); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Edge: TAppBarEdge read FEdge write SetAppBarEdge;
property TopMost: Boolean read FTopMost write SetTopMost default True;
end;

var
AppBar: TAppBar;

implementation

{$R *.DFM}

uses Main;

const
DEF_APPBAR_WIDTH = 40;
DEF_APPBAR_HEIGHT = 35;

var
AppBarMsg: UINT = 0;

constructor TAppBar.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// set up the TAppBarData record
with FABD do
begin
cbSize := SizeOf(FABD);
hWnd := Handle;
uCallbackMessage := AppBarMsg;
end;
// Inform the shell of the new AppBar
if SendAppBarMsg(ABM_NEW) = 0 then
raise EAppBarError.Create('Failed to create AppBar');
// Initialize the position
SetAppBarPos(ABE_TOP);
FTopMost := True;
FLastChecked := Top1;
end;

destructor TAppBar.Destroy;
begin
// Must inform shell that the AppBar is going away
SendAppBarMsg(ABM_REMOVE);
inherited Destroy;
end;

procedure TAppBar.WMWindowPosChanged(var M: TMessage);
begin
inherited;
// Must inform shell that the AppBar position has changed
SendAppBarMsg(ABM_WINDOWPOSCHANGED);
end;

procedure TAppBar.WMActivate(var M: TMessage);
begin
inherited;
// Must inform shell that the AppBar window was activated
SendAppBarMsg(ABM_ACTIVATE);
end;

bob008 2008-09-05
  • 打赏
  • 举报
回复
HOOK 这个WM_GETMINMAXINFO
加载更多回复(5)

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧