win32:检测开始菜单是否自动隐藏?

时间:2010-10-26 17:04:09

标签: windows winapi screen resolution

我想在屏幕底部放置一个窗口。如果出现开始菜单,我希望它位于开始菜单的顶部。如果它不是(或它是自动隐藏的),我仍然希望它与开始菜单在那里时的位置相同,这意味着会有几个像素的间隙。

目前我得到了显示器工作区,将窗口放在底部,并且总是偏移20个像素左右。如果没有开始菜单,这很有效。但是,如果是,工作区域也会缩小(应该如此),我最终会双重抵消。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

要使屏幕的工作区域不被系统任务栏或应用程序桌面工具栏遮挡,您可以将SystemParametersInfo()SPI_GETWORKAREA一起用作 uiAction 参数。 pvParam 参数必须指向接收工作区坐标的RECT结构,以虚拟屏幕坐标表示。例如:

  RECT rectWorkArea;
  SystemParametersInfo(SPI_GETWORKAREA, 0, &rectWorkArea, 0);

正如您在评论中所说,要获取任务栏的边界矩形,我们可以调用SHAppBarMessage(ABM_GETTASKBARPOS, ...)

要确定任务栏的位置(无论当前位于屏幕的底部,顶部,左侧还是右侧),您可以使用以下计算:

  type
    TTaskBarPos = (_TOP, _BOTTOM, _LEFT, _RIGHT);
  var
    iScrW, iScrH: Longint;

  iScrW := GetSystemMetrics(SM_CXSCREEN);
  iScrH := GetSystemMetrics(SM_CXSCREEN);

  if (rectTaskbar.Top > iScrH div 2) and (rectTaskbar.Right >= iScrW) then
    Result := _BOTTOM
  else if (rectTaskbar.Top < iScrH div 2) and (rectTaskbar.Bottom <= iScrW div 2) then
    Result := _TOP
  else if (rectTaskbar.Left < iScrW div 2) and (rectTaskbar.Top <= 0) then
    Result := _LEFT
  else
    Result := _RIGHT;

它们应足以解决您当前的问题。但是,如果您需要知道(出于其他原因)自动隐藏和始终在线状态的当前任务栏设置,您可以使用SHAppBarMessage(ABM_GETSTATE, ...)

如果您需要通知任务栏的自动隐藏或始终在线状态已更改,则必须拦截ABN_STATECHANGE消息。

答案 1 :(得分:0)

您正在项目中使用或访问.NET吗?

如果是这样,您可以使用Screen.PrimaryScreen.WorkingArea.Height属性来确定除任务栏之外的屏幕底部。

您还可以通过获取Screen.PrimaryScreen.Bounds.Height属性(其中包含总高度值中的任务栏)来获取总屏幕高度。

比较这些值,如果它们相同,则不存在任务栏。否则,任务栏就是,您可以相应地进行调整。