15,979
社区成员
发帖
与我相关
我的任务
分享
/****************************************************************************
主要思路是在处理主窗口的WM_WINDOWPOSCHANGED消息,并让指定窗口移动。
此方法可扩展应用到需要窗口跟随的很多场景中
win10 + vs2008 编译通过
代码仅供参考!
****************************************************************************/
#define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料
#include <windows.h>
#include <tchar.h>
/****************************************************************************
浮动在标题栏的窗口
****************************************************************************/
HWND g_WndOnTitle;
namespace WndOnTitle
{
WNDPROC g_OldWndProc=NULL;
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
// make mouse click no lost focus
case WM_MOUSEACTIVATE:
return MA_NOACTIVATE;
case WM_RBUTTONDOWN:
{
::MessageBox(NULL,TEXT("for test"),_T("标题"),MB_OK);
}
break;
}
return ::CallWindowProc(g_OldWndProc, hWnd, message, wParam, lParam); // 注意是CallWindowProc 而非 DefWindowProc
}
};
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// By default, the DefWindowProc function sends the WM_SIZE and WM_MOVE messages to the window.
// The WM_SIZE and WM_MOVE messages are not sent if an application handles the WM_WINDOWPOSCHANGED message
// without calling DefWindowProc. It is more efficient to perform any move or size change processing during
// the WM_WINDOWPOSCHANGED message without calling DefWindowProc.
case WM_WINDOWPOSCHANGED:
{
LPWINDOWPOS lpwndpos = ((LPWINDOWPOS)lParam) ;
::SetWindowPos(g_WndOnTitle,NULL,lpwndpos->x+40,lpwndpos->y+4,0,0,SWP_NOSIZE|SWP_NOACTIVATE);
return ::DefWindowProc(hWnd, message, wParam, lParam); //调用原来的窗口过程
}
break;
case WM_CLOSE:
::DestroyWindow(hWnd);
PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
WNDCLASS wndcls;
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.lpszMenuName = NULL;
wndcls.hInstance = NULL;
wndcls.style = CS_HREDRAW|CS_VREDRAW;
wndcls.hCursor = LoadCursor(NULL,IDC_ARROW);
wndcls.lpszClassName = _T("Demo_MainWnd");
wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndcls.hIcon = LoadIcon(::GetModuleHandle(NULL),NULL);
wndcls.lpfnWndProc = WndProc;
if (!RegisterClass(&wndcls))
return 0;
HWND hWnd = CreateWindowEx(NULL,_T("Demo_MainWnd"),_T("Demo"),WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN ,
0,0,200,200,NULL,NULL,NULL,NULL) ;
ShowWindow(hWnd,SW_SHOWNORMAL);
UpdateWindow(hWnd);
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//创建标题栏上面的窗口
RECT rect;
GetWindowRect(hWnd,&rect);
g_WndOnTitle=CreateWindowEx(NULL, _T("#32770"),_T("Demo"),WS_POPUP, rect.left+40,rect.top+4,50,25,hWnd,NULL,NULL,NULL) ;
::ShowWindow(g_WndOnTitle,SW_SHOWNOACTIVATE);
WndOnTitle::g_OldWndProc= (WNDPROC)::SetWindowLongPtr(g_WndOnTitle, GWLP_WNDPROC, (LONG_PTR)WndOnTitle::WndProc ) ;
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}