返回首页


{S0}简介
我搜索互联网上的一个简单的方法来实现一个AppBar(桌面应用程序的工具栏),但很多次都没有成功。微软提供了一些像SHAppBarMessage(A3})WINAPI shell函数。我尝试过了,但是这不是我的预期,因为壳牌AppBars重组桌面到合适的工具栏,而我想要一个滑杆,不干扰其他应用程序窗口或桌面上的图标。
所以,我已经开发了一个单一的MFC对象,CAppBarMngr,与应用程序的源代码最小的变化,让几乎所有的应用程序成为一个滑动AppBar。既然是必要的回应以外的应用程序窗口的鼠标动作,我不得不实施一个全球性的鼠标钩子,这就需要生成一个DLL,但你没有DLL的内部处理,只是为了与您的软件分发。整体设计
是一类:CAppBarMngr,将负责为从桌面屏幕的左边缘或右边缘的滑动应用程序的主框架。正如我刚才所说,是一个全局钩子需要作出适当反应的鼠标光标的位置(即侧缘已达到)。
传统,一个全局钩子是实施,发送通过其HWND的处理程序(钩子的DLL可以不被MFC的启用),需要在应用程序代码的几个修改接收和管理的钩子消息的消息应用程序的窗口的DLL 。然而,为了避免这种情况,我已经尝试过不同的方法:将消息发送到辅助线程,如下所述。CAppBarMngr类
这个类是从CWinThread派生,所以它能够接收邮件的发送使用WINAPI PostThreadMessage()函数,通过实施的PreTranslateMessage()事件。另外这个类有一些其他方面的职责:将钩子DLL的包装,并处理窗口移动(滑动)。
CAppBarMngr只有一个公共成员:init()函数。它将被用于链接与管理的窗口管理器。在源代码中所述,它有三个参数:

//------------------------------------------------------

// Function:  Init   - Loads DLL functions and initilize mouse hook

// Arguments: _hWnd  - Handler of window to manage

//            _width - Desired width of managed window

//            _left  - True if window is left side docked, false if right sided

// Returns:   APPBARHOOK_DLLERROR - An error has occurred while loading DLL functions

//            APPBARHOOK_ALREADYHOOKED - Another instance has already hooked the mouse

//            APPBARHOOK_SUCCESS - All is OK

//---------------------------------------------------------------------



int CAppBarMngr::Init(HWND _hWnd, int _width, bool _left)
如何使用它
这是所有你所要做的,落实到你的应用程序AppBar的:插入您的MFC项目的AppBarMngr.cpp和AppBarMngr.h文件。放上#包括"AppBarMngr.hquot;到您的主文件(创建主窗口)。创建你的主窗口,通常分为yourapp::InitInstance()中。创建一个MFC线程:AfxBeginThread()函数如下所示,保存一个指向它的指针。调用init方法,指定窗口的HWND的处理程序,所需的宽度和边缘。验证如果init成功返回。
下面是演示应用程序的代码部分:{C}
这是所有你必须​​做的。另外,不要忘记您的可执行应用程序分发的钩子DLL(AppBarHook.dll),它必须驻留在同一目录中才能正常工作。为免单实例的控制
作为运行两份相同AppBar计划的,它是没有意义的,init()函数是一个钩子已经使用(返回APPBARHOOK_ALREADYHOOKED)的通知,因此,您可以使用它,以避免第二个实例运行。请注意在上面的例子最后几行,如果已经使用挂钩,然后它返回FALSE来关闭应用程序。挂钩项目
我要开发一个项目,以实现全局鼠标钩子DLL。它只有一个文件:AppBarHook.cpp。我不想让一个钩子教程在这里,因为有几个伟大的文章在CodeProject。所以,我只会给你的一些细节。
通常的钩子技术节省了钩消息的接收窗口的窗口处理程序(HWND)。我用一个线程ID,而不是,那为什么CAppBarMngr是一个线程对象。因此,消息是通过使用WINAPI::SendThreadMessage(),而不是::SendMessage()的功能。
钩子将检测CAppBarMngr可能感兴趣的鼠标事件。我说,可能因为钩子不知道窗口状态和位置,它知道只有约的管理优势和窗口的宽度。 MFC类会做剩下的工作。
钩子DLL出口只有一个功能:SetHook(),它创建的全局鼠标钩子,并节省所需的宽度和边缘。这就是所谓的CAppBarMngr。关于演示应用
我已经创建了一个简单的演示应用程序项目,用于测试目的。它没有框架,标题,菜单或边境,有一个简单的CFrameWnd的派生对象。我已经测试没有任何问题,这与其他标准的MFC窗口。
演示源是一个Visual C + + 6.0项目,但您将能够打开并自动转换成一个较新的Visual C版本。
如果您发现此应用程序中的任何错误,请不要在意它。这只是用于演示目的,它不是本文的意图。出于同样的原因,我不会形容其内部。。NET版本
我已要求这种控制的。NET版本几次。我已经开始工作。我会在下面的论坛留下的消息时,它已准备好。历史2005年5月3 - 第一版2008年7月9日 - 增加了多显示器支持

回答

评论会员:VaKa 时间:2011/12/04
微软提供了一些像SHAppBarMessage WINAPI shell函数(阅读)和一个古老的示例应用程序(AppBar.exe)。
我试了一下,但,这不是我的预期,因为壳牌AppBars重组桌面到合适的工具栏,而我想要一个滑杆,不干扰其他应用程序窗口或桌面上的图标。 AppBar重组在桌面上,适合的工具栏,如果该选项要求。
只要看看另一个例子appbar - Jefrey里希特运行shell(MSDN里面可以发现)

运行SHELLRUN.exe。移动鼠标在屏幕的上方 - AppBar出现。
右击它。
弹出菜单中检查自动隐藏选项。
现在AppBar隐藏和不打扰destop项目
评论会员:jpiquemal 时间:2011/12/04
简单而有效的
评论会员:会员2565756 时间:2011/12/04
这就是我想要的!!感谢
评论会员:海梅奥利瓦雷斯 时间:2011/12/04
您好,

我有一个滑动工具栏上的同类要求。
请让我知道我可以使用在C#。NET作为我的整个应用程序是用C#创建。NET。

这的确是非常迫切的。

感谢
评论会员:alexv1977 时间:2011/12/04
嗨,我我只是计划推出NET版本的这篇文章。会告诉你
如果你想自己做,你可以查看一些文章。NET与全球挂钩。

最好的问候,
海梅。
评论会员:wayitech 时间:2011/12/04
有此功能,这将是非常有用的。NET
感谢,伟大的工作!

亚历克斯
评论会员:Sandro78 时间:2011/12/04
我尝试使用这个类,在我的对话框基的应用程序,
但失败了,我可以在我的基于对话框的应用程序使用这个类呢?
评论会员:duneth 时间:2011/12/04
是你可以使用这个库在一个对话框基地应用程序:

类CMainFrame:CFrameWnd的公共
{
.........................{ BR} CMyDialog m_dlgObject;
&# 160; .........................{ BR}}

的CMainFrame::OnCreate中(LPCREATESTRUCT lpCreateStruct)
{
m_dlgObject.Create(IDD_MYDIALOG,NULL);
& #160; .........................{ BR} int结果= appbar - GT的init(m_dlgObject.m_hWnd,300,TRUE);
.........................{ BR}
}
评论会员:_Stilgar_ 时间:2011/12/04
您好,
我们如何使用VB.NET或C#
评论会员:Djohnnie 时间:2011/12/04
嘿,

不错的主意和代码!

当你加载的应用程序和有是一个具有焦点的窗口的背后(最大化) - 然后你看到窗口失去它的重点,但它的大约15%是仍然在左侧集中,和然后它得到粉刷快速毛刺。这是一个小故障,你可能可以很容易解决创建与SW_HIDE栏。
我没有时间尚未通过代码,但我想这是要走的路。 Stilgar。

评论会员:海梅奥利瓦雷斯 时间:2011/12/04
你见过双显示器上的效果
如果栏进入屏幕右侧的边框幻灯片,它只是移动{S2}
评论会员:ShanGill 时间:2011/12/04
不是真的,我会尝试检查
左边的画面,这是相当有趣的右侧。不久,我将发布一个新版本。


海梅
评论会员:。海梅奥利瓦雷斯 时间:2011/12/04
这是我如何处理双显示器。顺便说一下,这是一个非常有用的概念。干得好,海梅奥利瓦雷斯!

有一个非常简单的API调用,GetClipBox(),您可以添加到CAppBarMngr代码:

INT CAppBarMngr:INIT(HWND _hWnd,INT _width,BOOL _left)
{
m_Module =::LoadLibrary的("Edge21TBHook.dll"); / /加载DLL
如果(!m_Module)
返回APPBARHOOK_DLLERROR;

m_fpSetHook =(TFSetHook)::GetProcAddress函数(m_Module,"SetHook"); / /载入功能

(m_fpSetHook){/ /如果函数已成功加载
m_pWindow =的CWnd::FromHandle(_hWnd)
m_bLeft = _left; / /设置方向和宽度
m_Width = _width;

{/ /获取显示面积多显示器使用
RECT RC
XWID,YHGT诠释十,Y,
HDC HDC =的GetDC(NULL)

GetClipBox(HDC,放大器; RC);  0;
ReleaseDC(NULL,HDC); X = rc.left;
为Y = rc.top;
XWID = rc.right - rc.left;
YHGT = rc.bottom - rc.top;
如果(m_bLeft)/ /制作第一张幻灯片
 60; SlideWindow(X,FALSE)
ELSE

SlideWindow(XWID m_Width,TRUE); }
/ /调用SetHook功能
如果((* m_fpSetHook)(此- GT; m_nThreadID,m_Width,m_bLeft)){
::FreeLibrary则(m_Module); / /清理DLL的引用
m_Module = NULL;
  ; 返回APPBARHOOK_ALREADYHOOKED / /已经上钩,也许第二个实例
}

返回APPBARHOOK_SUCCESS; / /所有是确定
}否则{
::FreeLibrary则(m_Module); / /清理DLL的引用
m_Module = NULL;
返回APPBARHOOK_DLLERROR;
}
}
评论会员:海梅奥利瓦雷斯 时间:2011/12/04
。山
我没有审查多年的这篇文章。我会尝试你的建议,并通知你。

最好的问候,
海梅
评论会员:。ShanGill 时间:2011/12/04
喜ShanGill,
我已检查过你的代码,但不知道你是否已经考虑更改DLL。
看看我更新的代码。

最好的问候,
海梅
评论会员:。海梅奥利瓦雷斯 时间:2011/12/04
海梅,
你是正确的 - 应予以调整,太钩。 MouseProc(),我改变了以下(见大胆- ED线):

...
如果(s_ThreadID){
/ /获取屏幕的绝对坐标
::GetCursorPos(PT);

/ /注意,我们只需要添加一个短块的箱


/ /获取多显示器使用的显示区域RECT RC
INT X,XWID;
HDC HDC =的GetDC(NULL)
GetClipBox(HDC,RC) ReleaseDC(NULL,HDC);X = 1 rc.left;
XWID = rc.right - rc.left;
(s_Left){/ / Appbar是左侧
(pt.xlt X)GT
::PostThreadMessage(s_ThreadID,WM_USER 2,0,0); / /可能要出现
否则,如果(pt.xgt; s_Width)
::PostThreadMessage(s_ThreadID,WM_USER 3,0,0); / /可能要消失
} {/ / Appbar是右侧
静态瓦特;
(pt.xgt; XWID - 2)
::PostThreadMessage(s_ThreadID,WM_USER 2,0,0); / /可能要出现
否则,如果(pt.xlt; xwid - s_width)GT
::PostThreadMessage(s_ThreadID,WM_USER 3,0,0); / /可能要消失
}
}
...
评论会员:alejrgr 时间:2011/12/04
喜山,
请问你测试我发送的代码?我没有双显示器,在这一刻。

最好的问候,
海梅
评论会员:。海梅奥利瓦雷斯 时间:2011/12/04
。HI

我想在VB6中使用源....这可能吗?

请写一个例子来做到这一点... ...因为我不知道该怎么办?

非常感谢!


评论会员:alejrgr 时间:2011/12/04
您好,
真诚,我真的不喜欢在VB中的那些东西,实在是痛苦的工作与挂钩。但我见过一个用VB appbar例如:[


祝你好运,
海梅
评论会员:。WREY 时间:2011/12/04
答案同样感谢


评论会员:海梅奥利瓦雷斯 时间:2011/12/04
它提供了其他许多美妙的思想的第一步

不过,我看到了一些改进的余地。例如,我是一些表面的改变使应用程序(插入额外的评论我的利益),那么,当我试图重新编译和链接,它不会由于其无法覆盖以前的可执行模块。我不得不重新编译之前删除"。exe"的文件,以获得一个干净的编译和链接。

一个很好的样本,不过!BR}


威廉

在真诚等opere特长
评论会员:游客 时间:2011/12/04
!拉维Bhavnani。我认为这是没有问题的,当您尝试重新编译,要么是EXE或DLL,应用程序必须不lauched,但我没有任何时间删除。exe文件,如你所说。海梅
。jaime_olivares
评论会员:游客 时间:2011/12/04
我使用一个定时器来处理{A5}]的应用程序自动隐藏我写的。您可能要检查其行为可能的想法。拉维/我的新的一年的分辨率:2048×1536{A6}ravib@ravib.com