我正在开发一个工具栏应用程序(我知道这很古老,但这是要求)并且遇到了一些麻烦。我在许多其他API调用中使用win32 API SHAppBarMessage
函数来完成此任务。但是,我遇到了一个奇怪的问题。
首次启动我的应用程序时,它似乎停靠在屏幕的顶部或底部,具体取决于之前的位置。然而,在第一次启动时,在我的代码完成运行之后,工具栏将恢复到大方块中的屏幕中心。再一次,我无法进入发生这种情况的代码,它就在其他地方。
有趣的是,如果我在第一次启动时将Handle
设置为IntPtr.Zero
,则不会发生这种情况。它会导致其他错误,并不是一个可行的解决方法,但它是关于这个问题的更多信息。
以下是一些代码,用于上下文。
“正确”句柄的设置:
AppStartModule.Handle = new WindowInteropHelper(AppStartModule.ToolBarWindow).Handle;
变通方法0句柄的设置:
AppStartModule.Handle = IntPtr.Zero;
提前致谢,如果您需要更多信息,请告诉我们。
编辑:我还尝试覆盖WndProc
事件以防止窗口移动。这也失败了。
编辑:以下代码
internal static bool RegisterAppBar(IntPtr hWnd, int uCallbackMessage)
{
APP_BAR_DATA abd = new APP_BAR_DATA();
abd.cbSize = Marshal.SizeOf(abd);
abd.hWnd = hWnd;
abd.uCallbackMessage = uCallbackMessage;
int retVal = SHAppBarMessage(ABM_NEW, ref abd);
return retVal != 0;
}
internal static void UnregisterAppBar(IntPtr hWnd)
{
APP_BAR_DATA abd = new APP_BAR_DATA();
abd.cbSize = Marshal.SizeOf(abd);
abd.hWnd = hWnd;
SHAppBarMessage(ABM_REMOVE, ref abd);
}
internal static void DockAppBar(IntPtr hWnd, int edge, Size idealSize, bool bAutoHideState)
{
APP_BAR_DATA abd = new APP_BAR_DATA();
abd.cbSize = Marshal.SizeOf(abd);
abd.hWnd = hWnd;
abd.uEdge = edge;
APP_BAR_DATA appBarData = new APP_BAR_DATA();
appBarData.cbSize = (int)Marshal.SizeOf(appBarData);
int retVal = SHAppBarMessage(ABM_GETTASKBARPOS, ref appBarData);
if (appBarData.uEdge != 0)
{
abd.rc.left = 0;
}
else
{
abd.rc.left = appBarData.rc.right;
}
abd.rc.right = GetSystemMetrics(SM_CXFULLSCREEN);
if (edge == ABE_TOP)
{
abd.rc.bottom = idealSize.Height;
}
else
{
abd.rc.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
abd.rc.top = abd.rc.bottom - idealSize.Height;
}
// Query the system for an approved size and position.
if (!bAutoHideState)
{
SHAppBarMessage(ABM_QUERYPOS, ref abd);
}
// Adjust the rectangle, depending on the edge to which the
// appbar is anchored.
switch (edge)
{
case ABE_TOP:
abd.rc.bottom = abd.rc.top + idealSize.Height;
break;
case ABE_BOTTOM:
abd.rc.top = abd.rc.bottom - idealSize.Height;
break;
}
// Pass the final bounding rectangle to the system.
if (!bAutoHideState)
{
SHAppBarMessage(ABM_SETPOS, ref abd);
}
// Move and size the appbar so that it conforms to the
// bounding rectangle passed to the system.
if (appBarData.uEdge == 0)
{
MoveWindow(abd.hWnd, abd.rc.left, abd.rc.top, abd.rc.right - abd.rc.left, abd.rc.bottom - abd.rc.top, true);
}
else
{
MoveWindow(abd.hWnd, abd.rc.left, abd.rc.top, abd.rc.right - abd.rc.left + appBarData.rc.right - appBarData.rc.left, abd.rc.bottom - abd.rc.top, true);
}
}