怎样在Desktop上建一个toolbar,象任务栏一样?(300分)

  • 主题发起人 主题发起人 kimfeng
  • 开始时间 开始时间
网上很多代码的,找找吧,我随手帮你找了一个,不过先要注册:
http://www.vcfan.com/delphi/down_files.asp?id=600
 
用APPBAR 1.4
www.2ccc.com上有下载的.
 
这个是你想要的控件:
http://www.fixdown.com/soft/14189.asp?soft=scdown
 
APPBARDATA AppBar; // 应用程序桌面任务栏结构

先hWndAppBar=CreateWindowEx(WS_EX_TOOLWINDOW,// 工具窗口风格
"AppBarClass",
"AppBar",
WS_POPUP | WS_THICKFRAME | WS_CLIPCHILDREN,
0,0,DEF_APPBAR_WIDTH, DEF_APPBAR_HEIGHT,
NULL,
NULL,
hInstance,
NULL);

然后
// 填写APPBARDATA结构.
AppBar.cbSize = sizeof(APPBARDATA);
AppBar.hWnd = hWndAppBar;

// 提供一个回调通知消息标识符.
AppBar.uCallbackMessage = APPBAR_CALLBACK;

// 注册应用程序桌面任务栏.
if (!SHAppBarMessage(ABM_NEW, &AppBar))
break;

// 设置应用程序桌面任务栏的默认位置和尺寸.
AppBarPosChanged(ABE_TOP, &AppBar);

ShowWindow(hWndAppBar, SW_SHOW);

设定APPBAR_CALLBACK,消息循环处理
LRESULT CALLBACK AppBarWndProc(HWND hWnd,UINT message, WPARAM wParam,LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
break;

case WM_DESTROY:
break;

case WM_WINDOWPOSCHANGED:
case WM_ACTIVATE:
{
// 通知系统,应用程序状态栏已经被激活。
APPBARDATA abd;
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = hWnd;
abd.lParam = (LONG)NULL;
SHAppBarMessage(ABM_ACTIVATE, &abd);
break;
}

case WM_COMMAND:
break;

case APPBAR_CALLBACK:
// 处理应用程序状态栏回调通知消息。
AppBarCallback(hWnd, message, wParam, lParam);
return 0;

//下面处理鼠标击键消息,用来实现应用程序桌面任务栏的拖放。
//这里采用一种很简单的算法来决定拖放的目的地。
case WM_LBUTTONDOWN:
SetCapture( hWnd );
break;
case WM_LBUTTONUP:
ReleaseCapture( );
point.x = (LONG)(short int)LOWORD(lParam);
point.y = (LONG)(short int)HIWORD(lParam);
ClientToScreen(hWndAppBar, &point);
if( point.x < cxScreen/4 )
AppBarClicked(IDM_LEFT,(APPBARDATA *)&AppBar);
else if( point.y < cyScreen/4 )
AppBarClicked(IDM_TOP,(APPBARDATA *)&AppBar);
else if( point.x > 3*cxScreen/4 )
AppBarClicked(IDM_RIGHT,(APPBARDATA *)&AppBar);
else if( point.y > 3*cyScreen/4 )
AppBarClicked(IDM_BOTTOM,(APPBARDATA *)&AppBar);
break;

default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}

/****************************************************************************
*
* 回调函数: AppBarCallback(HWND, UINT, WPARAM, LPARAM)
*
* 用途: 处理应用程序桌面任务栏通知消息.
*
****************************************************************************/
void AppBarCallback(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
UINT uState;

switch (wParam)
{
case ABN_STATECHANGE:
// 检查应用程序桌面任务栏的显示方式状态, 并作相应处理。
uState = SHAppBarMessage(ABM_GETSTATE, &AppBar);

SetWindowPos(hWnd,
(ABS_ALWAYSONTOP & uState) ? HWND_TOPMOST : HWND_BOTTOM,
0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
break;

case ABN_FULLSCREENAPP:
// 当启动或关闭一个全屏幕应用程序时, 根据应用程序桌面任务栏的
// 显示方式状态, 调整应用程序桌面任务栏的显示。
uState = SHAppBarMessage(ABM_GETSTATE, &AppBar);

if (lParam)
{
SetWindowPos(hWnd,
(ABS_ALWAYSONTOP & uState) ? HWND_TOPMOST : HWND_BOTTOM,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
else
{
if (uState & ABS_ALWAYSONTOP)
SetWindowPos(hWnd, HWND_TOPMOST,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}

case ABN_POSCHANGED:
// 任务栏栏或其他应用程序桌面任务栏改变了尺寸或位置 。
AppBarPosChanged(AppBar.uEdge, &AppBar);
break;
}
}

/****************************************************************************
*
* 函数: AppBarPosChanged(UINT, APPBARDATA *)
*
* 用途: 调整应用程序桌面任务栏的尺寸和位置.
*
****************************************************************************/
void PASCAL AppBarPosChanged(UINT uEdge, APPBARDATA *abd)
{
RECT rcl;

// 取屏幕坐标尺寸.
rcl.left = rcl.top = 0;
rcl.right = cxScreen;
rcl.bottom = cyScreen;

switch (uEdge)
{
case ABE_TOP:
abd->rc.left = abd->rc.top = 0;
abd->rc.right = rcl.right;
abd->rc.bottom = DEF_APPBAR_HEIGHT;
break;

case ABE_BOTTOM:
abd->rc.left = 0;
abd->rc.top = rcl.bottom - DEF_APPBAR_HEIGHT;
abd->rc.right = rcl.right;
abd->rc.bottom = rcl.bottom;
break;

case ABE_LEFT:
abd->rc.left = abd->rc.top = 0;
abd->rc.right = DEF_APPBAR_WIDTH;
abd->rc.bottom = rcl.bottom;
break;

case ABE_RIGHT:
abd->rc.top = 0;
abd->rc.left = rcl.right - DEF_APPBAR_WIDTH;
abd->rc.right = rcl.right;
abd->rc.bottom = rcl.bottom;
break;
}

// 让系统对应用程序桌面任务栏的位置作适当调整.
SHAppBarMessage( ABM_QUERYPOS, abd);

switch (uEdge)
{
case ABE_LEFT:
abd->rc.right = abd->rc.left + DEF_APPBAR_WIDTH;
break;

case ABE_RIGHT:
abd->rc.left = abd->rc.right - DEF_APPBAR_WIDTH;
break;

case ABE_TOP:
abd->rc.bottom = abd->rc.top + DEF_APPBAR_HEIGHT;
break;

case ABE_BOTTOM:
abd->rc.top = abd->rc.bottom - DEF_APPBAR_HEIGHT;
break;
}

// 设定应用程序桌面任务栏的最终位置和尺寸.
SHAppBarMessage(ABM_SETPOS, abd);

MoveWindow(abd->hWnd, abd->rc.left, abd->rc.top,
abd->rc.right, abd->rc.bottom, TRUE);

if ((uEdge == ABE_TOP) || (uEdge == ABE_BOTTOM))
{
MoveWindow(hWndButtonProp, 3, 0, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
MoveWindow(hWndButtonLeft, BUTTON_WIDTH+20, 0, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
MoveWindow(hWndButtonRight, BUTTON_WIDTH*2+23, 0, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
MoveWindow(hWndButtonTop, BUTTON_WIDTH*3+26, 0, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
MoveWindow(hWndButtonBottom, BUTTON_WIDTH*4+29, 0, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
MoveWindow(hWndButtonClose, cxScreen-BUTTON_WIDTH-30, 0, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
}
else
{
MoveWindow(hWndButtonProp, 2, 3, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
MoveWindow(hWndButtonLeft, 2, BUTTON_HEIGHT+20, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
MoveWindow(hWndButtonRight, 2, BUTTON_HEIGHT*2+23, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
MoveWindow(hWndButtonTop, 2, BUTTON_HEIGHT*3+26, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
MoveWindow(hWndButtonBottom, 2, BUTTON_HEIGHT*4+29, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
MoveWindow(hWndButtonClose, 2, cyScreen-BUTTON_HEIGHT*2-30, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
}
}
补充:漏了一点东西,先要注册应用程序桌面任务栏窗口类
WNDCLASS wcAppBar;
wcAppBar.style = 0 ;
wcAppBar.lpfnWndProc = (WNDPROC)AppBarWndProc;
wcAppBar.cbClsExtra = 0;
wcAppBar.cbWndExtra = 0;
wcAppBar.hInstance = hInstance;
wcAppBar.hIcon = LoadIcon(hInstance, "SHELLFUN_ICON");
wcAppBar.hCursor = LoadCursor(NULL, IDC_ARROW);
wcAppBar.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
wcAppBar.lpszMenuName = NULL;
wcAppBar.lpszClassName = "AppBarClass";

RegisterClass(&wcAppBar);

上面代码中响应鼠标消息处理的AppBarClicked是自定义函数,在APPBAR上建“上下左右”四个按钮实现位置调整,IDM_TOP等是自定义按键消息。函数如下:
void AppBarClicked(UINT message,APPBARDATA * pabd)
{
switch (message)
{
case IDM_LEFT:
AppBarPosChanged(ABE_LEFT, pabd);
break;

case IDM_RIGHT:
AppBarPosChanged(ABE_RIGHT, pabd);
break;

case IDM_TOP:
AppBarPosChanged(ABE_TOP, pabd);
break;

case IDM_BOTTOM:
AppBarPosChanged(ABE_BOTTOM, pabd);
break;

case IDM_APPBARCLOSE:
PostMessage(hWndMain, WM_COMMAND,
(WPARAM)IDM_REMOVE, (LPARAM)NULL);
break;


}
}


 
任务栏也是个窗口,不过它的parent是桌面

用简单的方法处理,参考:
procedure TfmNotify.Createparams(var params: TCreateParams);
begin
inherited CreateParams(Params);
with params do
begin
params.Style:=WS_POPUP or WS_BORDER;
Params.ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
params.WndParent:=getDeskTopWindow;
end;
end;
 
后退
顶部