📄 dockwindow.c
字号:
#include <windows.h>
#include <tchar.h>
#include "DockWindow.h"
#define MAX_DOCK_WINDOWS 64
static HWND hDockList[MAX_DOCK_WINDOWS];
static int nNumDockWnds = 0;
static TCHAR szDockClass[] = _T("DockWnd32");
static ATOM aDockClass = 0;
static HWND GetOwner(HWND hwnd)
{
return GetWindow(hwnd, GW_OWNER);
}
static BOOL IsOwnedBy(HWND hwndMain, HWND hwnd)
{
return (hwnd == hwndMain) || (GetOwner(hwnd) == hwndMain);
}
void TogglePopupStyle(HWND hwnd)
{
DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE);
if(dwStyle & WS_CHILD)
{
SetWindowLong(hwnd, GWL_STYLE, (dwStyle & ~WS_CHILD) | WS_POPUP);
SetParent(hwnd, NULL);
}
else
{
SetWindowLong(hwnd, GWL_STYLE, (dwStyle & ~WS_POPUP) | WS_CHILD);
SetParent(hwnd, GetOwner(hwnd));
}
}
//
// This function only returns the popups which belong
// to the specified "main" window
//
// hwndMain - handle to top-level owner of the popups to retrieve
// hwndList - where to store the list of popups
// nItems - [in] - size of hwndList, [out] - returned no. of windows
// fIncMain - include the main window in the returned list
//
int GetPopupList(HWND hwndMain, HWND hwndList[], int nSize, BOOL fIncMain)
{
int i, count = 0;
if(hwndList == 0)
return 0;
for(i = 0; i < nNumDockWnds && i < nSize; i++)
{
if(IsOwnedBy(hwndMain, hDockList[i]))
hwndList[count++] = hDockList[i];
}
if(fIncMain && count < nSize)
{
hwndList[count++] = hwndMain;
}
return count;
}
//
// Dock window procedure
//
static LRESULT CALLBACK DockWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
int i;
switch(msg)
{
case WM_NCCREATE:
// Add this one to list of dock-windows.
if(nNumDockWnds < MAX_DOCK_WINDOWS)
{
hDockList[nNumDockWnds++] = hwnd;
return TRUE;
}
else
{
return FALSE;
}
case WM_NCDESTROY:
// remove this window from the list of dock-windows
for(i = 0; i < nNumDockWnds; i++)
{
if(hDockList[i] == hwnd)
{
for( ; i < nNumDockWnds - 1; i++)
{
hDockList[i] = hDockList[i+1];
}
nNumDockWnds--;
break;
}
}
return 0;
case WM_NCACTIVATE:
return HANDLE_NCACTIVATE(GetOwner(hwnd), hwnd, wParam, lParam);
case WM_DESTROY:
return 0;
case WM_CLOSE:
DestroyWindow(hwnd);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
static ATOM InitDockWndClass()
{
WNDCLASSEX wndclass;
ZeroMemory(&wndclass, sizeof(wndclass));
//Window class for the main application parent window
wndclass.cbSize = sizeof(wndclass);
wndclass.style = 0;
wndclass.lpfnWndProc = DockWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = GetModuleHandle(0);
wndclass.hIcon = 0;
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = szDockClass;
wndclass.hIconSm = 0;
return RegisterClassEx(&wndclass);
}
//
// Create a floating dock-window
//
HWND CreateDockWnd(HWND hwndParent, TCHAR szCaption[], int x, int y, int width, int height)
{
HWND hwnd;
if(aDockClass == 0)
aDockClass = InitDockWndClass();
hwnd = CreateWindowEx(
WS_EX_TOOLWINDOW,
szDockClass, szCaption,
WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU | WS_CLIPCHILDREN,
x,
y,
width,
height,
hwndParent,
NULL,
GetModuleHandle(0),
NULL);
SetWindowText(hwnd, szCaption);
return hwnd;
}
//
// The main window of app should call this in response to WM_ENABLE
//
// hwndMain - handle to top-level owner window
// hwnd - handle to window which received message (can be same as hwndMain)
//
LRESULT HANDLE_ENABLE(HWND hwndMain, HWND hwnd, WPARAM wParam, LPARAM lParam)
{
static HWND hwndList[MAX_DOCK_WINDOWS+1];
int i, nNumWnds;
HWND hParam = (HWND)lParam;
nNumWnds = GetPopupList(hwndMain, hwndList, MAX_DOCK_WINDOWS+1, FALSE);
for(i = 0; i < nNumWnds; i++)
{
if(hwndList[i] != hwnd)
{
EnableWindow(hwndList[i], wParam);
}
}
//just do the default
return DefWindowProc(hwnd, WM_ENABLE, wParam, lParam);
}
//
// The main window of app should call this in response to WM_NCACTIVATE
//
// hwndMain - handle to top-level owner window
// hwnd - handle to window which received message (can be same as hwndMain)
//
LRESULT HANDLE_NCACTIVATE(HWND hwndMain, HWND hwnd, WPARAM wParam, LPARAM lParam)
{
static HWND hwndList[MAX_DOCK_WINDOWS+1];
int i, nNumWnds;
HWND hParam = (HWND)lParam;
BOOL fKeepActive = wParam;
BOOL fSyncOthers = TRUE;
nNumWnds = GetPopupList(hwndMain, hwndList, MAX_DOCK_WINDOWS+1, TRUE);
// UNDOCUMENTED FEATURE:
// if the other window being activated/deactivated (i.e. NOT this one)
// is one of our popups, then go (or stay) active, otherwise.
for(i = 0; i < nNumWnds; i++)
{
if(hParam == hwndList[i])
{
fKeepActive = TRUE;
fSyncOthers = FALSE;
break;
}
}
// If this message was sent by the synchronise-loop (below)
// then exit normally
if(hParam == (HWND)-1)
{
return DefWindowProc(hwnd, WM_NCACTIVATE, fKeepActive, 0);
}
// This window is about to change (inactive/active).
// Sync all other popups to the same state
if(fSyncOthers == TRUE)
{
for(i = 0; i < nNumWnds; i++)
{
//DO NOT send this message to ourselves!!!!
if(hwndList[i] != hwnd && hwndList[i] != hParam)
SendMessage(hwndList[i], WM_NCACTIVATE, fKeepActive, (LONG)-1);
}
}
return DefWindowProc(hwnd, WM_NCACTIVATE, fKeepActive, lParam);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -