首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在Windows窗体应用程序设置中记录窗口位置

在Windows窗体应用程序设置中记录窗口位置的方法有多种,其中常见的方法是使用Windows事件跟踪(ETW)系统。在Windows中,ETW系统可以自动记录应用程序内部的操作和事件,使得我们可以根据这些信息推断应用程序的设置和运行时状态。在这里,我们将介绍如何使用ETW系统记录应用程序位置信息的方法。

  1. 首先,您需要确保Windows ETW系统已启用。在Windows 10中,可以通过以下步骤启用ETW系统:
  • 打开“控制面板”应用程序。
  • 在搜索框中输入 "事件追踪",然后从搜索结果中选择 "事件跟踪"。
  • 点击 "事件跟踪配置",进入"事件跟踪管理器" 窗口。
  • 在 "事件分类" 中,添加分类 "etw"。
  • 点击 "确定" 或应用更改,关闭窗口。
  • 再次点击 "确定",启用ETW。
  1. 在完成ETW系统配置之后,您可以在Windows窗体应用程序中使用一些常见的事件跟踪API来实现位置记录。例如,您可以使用以下代码记录应用程序的位置和尺寸信息:
代码语言:txt
复制

int32_t MainWindow::RecordPosition()

{

代码语言:txt
复制
   HRESULT hr;
代码语言:txt
复制
   ULONGLONG ullTag = RegisterWindowMessageA("PositionRecord");
代码语言:txt
复制
   IPropertyStore *pPropStore = nullptr;
代码语言:txt
复制
   hr = pView->get_Item(PKEY_DragDropSavePosition,&pPropStore);
代码语言:txt
复制
   if (SUCCEEDED(hr)) {
代码语言:txt
复制
       PROPVARIANT propVar = {0};
代码语言:txt
复制
       propVar.vt = VT_I4;
代码语言:txt
复制
       propVar.lVal = sizeof(HWND) + sizeof(INT32_T);
代码语言:txt
复制
       PROPERTYKEY pkey_Hwnd;
代码语言:txt
复制
       pkey_Hwnd.fmtid = PROGID_DragDrop;
代码语言:txt
复制
       pkey_Hwnd.pid = ullTag;
代码语言:txt
复制
       hr = pPropStore->SetValue(PKEY_Hwnd, &PKEY_DragDropSavePosition, PROPID_DragDropHwnd, &propVar);
代码语言:txt
复制
       pPropStore->Release();
代码语言:txt
复制
   }
代码语言:txt
复制
   return S_OK;

}

LRESULT MainWindow::WMSysCommandEventHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)

{

代码语言:txt
复制
   if (IDM_TRACKMOVESTATE == m_dwWMSysCommand) {
代码语言:txt
复制
       RECORDPOS();
代码语言:txt
复制
       return 0;
代码语言:txt
复制
   }
代码语言:txt
复制
   bHandled = FALSE;
代码语言:txt
复制
   return 0;

}

static HMONITOR WINAPI TrackMoveHelper(HMONITOR SourceMonitor, HDWP DisplayChange, POINT TrackPoint, MONITORINFOEXW& MonitorInfo_New)

{

代码语言:txt
复制
   // Do the actual tracking move
代码语言:txt
复制
   return S_FALSE;

}

void MainWindow::TRACKMOUSEMOVE(POINT Local)

{

代码语言:txt
复制
   // Register tracking window handle and mouse position in Property Store to track mouse movement
代码语言:txt
复制
   // This will capture position at the next TRACKMOUSEMOVE() call
代码语言:txt
复制
   HRESULT hr;
代码语言:txt
复制
   PROPVARIANT propVar = {0};
代码语言:txt
复制
   propVar.vt = VT_I4;
代码语言:txt
复制
   propVar.lVal = sizeof(HWND) + sizeof(INT32_T);
代码语言:txt
复制
   PROPERTYKEY pkey_Hwnd;
代码语言:txt
复制
   pkey_Hwnd.fmtid = PROGID_DragDrop;
代码语言:txt
复制
   pkey_Hwnd.pid = ullTag;
代码语言:txt
复制
   hr = pView->put_Item(PKEY_DragDropHwnd,&PKEY_DragDropHwnd,PKEY_DragDropSavePosition,PropVar);
代码语言:txt
复制
   // Release the window Handle for Property Store
代码语言:txt
复制
   pView->Release();
代码语言:txt
复制
   // Set the window handle value in the mouse position Property Store
代码语言:txt
复制
   // This helps to capture the position at the same mouse position at the next TRACKMOUSEMOVE
代码语言:txt
复制
   PROPVARIANT tmpVar = PropVar;
代码语言:txt
复制
   tmpVar.vt = VT_BYREF| VT_UI4;
代码语言:txt
复制
   tmpVar.u4.lVal = Local.x + HWND_XPOS;
代码语言:txt
复制
   PropertyKey tmpKey = {PKEY_DragDropHwnd,nullptr,PKEY_DragDropSavePosition};
代码语言:txt
复制
   int res = pView->put_Item(PKEY_DragDropHwnd,&tmpKey,&tmpVar);
代码语言:txt
复制
   // Release the mouse position data in Property Store	

}

void MainWindow::SaveViewState()

{

代码语言:txt
复制
   // Use the event tracking to save the current position and size of the view
代码语言:txt
复制
   HRESULT hr;
代码语言:txt
复制
   ULONGLONG ullTag = RegisterWindowMessageA("ViewState");
代码语言:txt
复制
   IDropTarget *pDT = nullptr;
代码语言:txt
复制
   // Register object to receive WM_DROPFILES as Drop Events 
代码语言:txt
复制
   IDataObject *pDataobj = nullptr;
代码语言:txt
复制
   hr = GetDragDropTarget(GetSafeHwnd(), IID_PPV_ARGS(&pDT));
代码语言:txt
复制
   if (FAILED(hr)) throw;
代码语言:txt
复制
   hr = QueryInterface(pDT->GetSafeInterface(&pDataobj));
代码语言:txt
复制
   if (FAILED(hr)) throw;
代码语言:txt
复制
   const CLSID *pclsid= IID_PPV_ARGS(&IID_IDropTarget);
代码语言:txt
复制
   HGLOBAL hgDropGlobal = GlobalAlloc(0, FIELD_OFFSET(DropTarget,DataObject));
代码语言:txt
复制
   pDT->OnDrop(pclsid, pDataobj);
代码语言:txt
复制
   pDT->GetDropTarget()->GetInterface(IID_PPV\_ARGS(hgDropGlobal));
代码语言:txt
复制
   GlobalFree(hgDropGlobal);
代码语言:txt
复制
   // Register new ViewState
代码语言:txt
复制
   ULONGLONG ullViewStateTag = RegisterWindowMessageA("ViewState");
代码语言:txt
复制
   LONGLONG ullMinMaxX = 0x10016A5A2540 ull, ullMinMaxY = 0x10016A5A2548 ull, ullMinMaxW = 0x10016A5A1FE0 ull, ullMinMaxH = 0x10016A5A1FF8 ull;
代码语言:txt
复制
   CWindows::UpdateViewSizeMinMaxRect(ullMinMaxX, ullMinMaxY, ullMinMaxW, ullMinMaxH);
代码语言:txt
复制
   PropVariant propvar;
代码语言:txt
复制
   propvar.vt = VT_UI8;
代码语言:txt
复制
   propvar.ui8 = 0;
代码语言:txt
复制
   hr = pView->put\_PropVariant(PKEY\_DragDropSaveViewSizeMinMax rects, &propvar, ullTag);
代码语言:txt
复制
   // Record the ViewState as well 
代码语言:txt
复制
   CWindows::SetPropData(PKEY\_DragDropSaveViewState rects, &propvar, ullTag);
代码语言:txt
复制
   // Set the window handle value in the Viewstte Property Store
代码语言:txt
复制
   PROPVARIANT tmpVar = PropVar;
代码语言:txt
复制
   tmpVar.vt = VT_BYREF| VT_UI8;
代码语言:txt
复制
   tmpVar.u8 = 4096 ull;
代码语言:txt
复制
   propvar = PROPVARIANT(ullMinMaxW, ullMinMaxY, ullMinMaxX, ullMinMaxH);
代码语言:txt
复制
   hr = pView->put\_PropVariant(PKEY\_DragDropSaveViewState, &PKEY\_DragDropSaveViewState, propvar, ullTag);
代码语言:txt
复制
   // Release the window handle variable for Property Store
代码语言:txt
复制
   pView->Release();
代码语言:txt
复制
   // Release the dragged object data in Property Store
代码语言:txt
复制
   CWindows::DestroyDropGlobal(pDataobj);

}

代码语言:txt
复制

上述代码中的函数 RecordPosition() 用于记录应用程序的窗体位置信息,函数 TrackMoveHelper() 负责记录应用程序的窗体位置并进行移动操作;函数 TRACKMOUSEMOVE() 用于向 Windows 事件跟踪系统中注册鼠标的位置以记录窗体位置信息;函数 SaveViewState() 负责使用 Windows 事件跟踪系统保存应用程序的窗体位置和尺寸信息。这些函数的实现需要使用 ETW 系统提供的 API,具体使用方法可以参照 ETW 技术的官方文档。

  1. 在实现窗口位置记录之后,您可以使用 TRACKMOUSEMOVE() 函数在应用程序中触发 wm_mousemove 触发事件以持续记录应用程序的窗体位置,或者使用函数 SaveViewState() 在应用程序退出之后立即记录应用程序的窗体位置和尺寸信息。

这些方法可以帮助您记录Windows窗体应用程序的设置和运行时状态,以便您能够更好地管理应用程序的窗口位置和大小信息。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

领券