📄 dockingcont.cpp
字号:
/* set text and/or caption grid */
if (_isTopCaption == TRUE)
{
if (_isActive == TRUE)
{
/* fill background */
::FillRect(hDc, &rc, bgbrush);
rc.right -= 1;
rc.bottom -= 1;
}
else
{
/* fill background */
rc.right -= 1;
rc.bottom -= 1;
::FillRect(hDc, &rc, bgbrush);
/* draw grid lines */
HPEN hOldPen = (HPEN)::SelectObject(hDc, hPen);
MoveToEx(hDc, rc.left , rc.top , NULL);
LineTo (hDc, rc.right, rc.top );
LineTo (hDc, rc.right, rc.bottom );
LineTo (hDc, rc.left , rc.bottom );
LineTo (hDc, rc.left , rc.top);
}
/* draw text */
rc.left += 2;
rc.top += 1;
rc.right -= 16;
hOldFont = (HFONT)::SelectObject(hDc, _hFont);
::DrawText(hDc, _pszCaption, length, &rc, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
/* calculate text size and if its trankated... */
SIZE size = {0};
GetTextExtentPoint32(hDc, _pszCaption, length, &size);
_bCaptionTT = (((rc.right - rc.left) < size.cx) ? TRUE : FALSE);
::SelectObject(hDc, hOldFont);
}
else
{
/* create local font for vertical draw */
HFONT hFont;
if (_isActive == TRUE)
{
/* fill background */
::FillRect(hDc, &rc, bgbrush);
rc.right -= 1;
rc.bottom -= 1;
}
else
{
/* fill background */
rc.right -= 1;
rc.bottom -= 1;
::FillRect(hDc, &rc, bgbrush);
/* draw grid lines */
HPEN hOldPen = (HPEN)::SelectObject(hDc, hPen);
MoveToEx(hDc, rc.left , rc.top , NULL);
LineTo (hDc, rc.right, rc.top );
LineTo (hDc, rc.right, rc.bottom );
LineTo (hDc, rc.left , rc.bottom );
LineTo (hDc, rc.left , rc.top);
}
/* draw text */
rc.left += 1;
rc.top += HIGH_CAPTION;
/* to make ellipsis working */
rc.right = rc.bottom - rc.top;
rc.bottom += 14;
hFont = ::CreateFont(12, 0, 90 * 10, 0,
FW_NORMAL, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_ROMAN,
"MS Shell Dlg");
hOldFont = (HFONT)::SelectObject(hDc, hFont);
::DrawText(hDc, _pszCaption, length, &rc, DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX);
/* calculate text size and if its trankated... */
SIZE size = {0};
GetTextExtentPoint32(hDc, _pszCaption, length, &size);
_bCaptionTT = (((rc.bottom - rc.top) < size.cy) ? TRUE : FALSE);
::SelectObject(hDc, hOldFont);
::DeleteObject(hFont);
}
::DeleteObject(hPen);
::DeleteObject(bgbrush);
/* draw button */
HDC dcMem = ::CreateCompatibleDC(NULL);
/* select correct bitmap */
if ((_isMouseOver == TRUE) && (_isMouseDown == TRUE))
hBmpCur = ::LoadBitmap(_hInst, MAKEINTRESOURCE(IDB_CLOSE_DOWN));
else
hBmpCur = ::LoadBitmap(_hInst, MAKEINTRESOURCE(IDB_CLOSE_UP));
/* blit bitmap into the destination */
::GetObject(hBmpCur, sizeof(bmp), &bmp);
hBmpOld = (HBITMAP)::SelectObject(dcMem, hBmpCur);
hBmpNew = ::CreateCompatibleBitmap(dcMem, bmp.bmWidth, bmp.bmHeight);
rc = pDrawItemStruct->rcItem;
::SelectObject(hDc, hBmpNew);
if (_isTopCaption == TRUE)
::BitBlt(hDc, rc.right-bmp.bmWidth-CLOSEBTN_POS_LEFT, CLOSEBTN_POS_TOP, bmp.bmWidth, bmp.bmHeight, dcMem, 0, 0, SRCCOPY);
else
::BitBlt(hDc, CLOSEBTN_POS_LEFT, CLOSEBTN_POS_LEFT, bmp.bmWidth, bmp.bmHeight, dcMem, 0, 0, SRCCOPY);
::SelectObject(dcMem, hBmpOld);
::DeleteObject(hBmpCur);
::DeleteObject(hBmpNew);
::DeleteDC(dcMem);
::RestoreDC(hDc, nSavedDC);
}
eMousePos DockingCont::isInRect(HWND hwnd, INT x, INT y)
{
RECT rc;
eMousePos ret = posOutside;
::GetWindowRect(hwnd, &rc);
ScreenToClient(hwnd, &rc);
if (_isTopCaption == TRUE)
{
if ((x > rc.left) && (x < rc.right-HIGH_CAPTION) && (y > rc.top) && (y < rc.bottom))
{
ret = posCaption;
}
else if ((x > rc.right-(12+CLOSEBTN_POS_LEFT)) && (x < (rc.right-CLOSEBTN_POS_LEFT)) &&
(y > (rc.top+CLOSEBTN_POS_TOP)) && (y < (rc.bottom-CLOSEBTN_POS_TOP)))
{
ret = posClose;
}
}
else
{
if ((x > rc.left) && (x < rc.right) && (y > rc.top+HIGH_CAPTION) && (y < rc.bottom))
{
ret = posCaption;
}
else if ((x > rc.left+CLOSEBTN_POS_LEFT) && (x < rc.right-CLOSEBTN_POS_LEFT) &&
(y > (rc.top+CLOSEBTN_POS_TOP)) && (y < (rc.top+(12+CLOSEBTN_POS_LEFT))))
{
ret = posClose;
}
}
return ret;
}
/*********************************************************************************
* Process function of tab
*/
LRESULT DockingCont::runProcTab(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
static ToolTip toolTip;
switch (Message)
{
case WM_LBUTTONDOWN:
{
_beginDrag = TRUE;
return TRUE;
}
case WM_LBUTTONUP:
{
INT iItem = 0;
TCHITTESTINFO info = {0};
/* get selected sub item */
info.pt.x = LOWORD(lParam);
info.pt.y = HIWORD(lParam);
iItem = ::SendMessage(hwnd, TCM_HITTEST, 0, (LPARAM)&info);
SelectTab(iItem);
_beginDrag = FALSE;
return TRUE;
}
case WM_LBUTTONDBLCLK:
{
NotifyParent((_isFloating == true)?DMM_DOCK:DMM_FLOAT);
return TRUE;
}
case WM_MBUTTONUP:
{
INT iItem = 0;
TCITEM tcItem = {0};
TCHITTESTINFO info = {0};
/* get selected sub item */
info.pt.x = LOWORD(lParam);
info.pt.y = HIWORD(lParam);
iItem = ::SendMessage(hwnd, TCM_HITTEST, 0, (LPARAM)&info);
SelectTab(iItem);
/* get data and hide toolbar */
tcItem.mask = TCIF_PARAM;
::SendMessage(hwnd, TCM_GETITEM, iItem, (LPARAM)&tcItem);
/* notify child windows */
if (NotifyParent(DMM_CLOSE) == 0)
{
hideToolbar((tTbData*)tcItem.lParam);
}
return TRUE;
}
case WM_MOUSEMOVE:
{
INT iItem = 0;
TCHITTESTINFO info = {0};
/* get selected sub item */
info.pt.x = LOWORD(lParam);
info.pt.y = HIWORD(lParam);
iItem = ::SendMessage(hwnd, TCM_HITTEST, 0, (LPARAM)&info);
if ((_beginDrag == TRUE) && (wParam == MK_LBUTTON))
{
SelectTab(iItem);
/* send moving message to parent window */
_dragFromTab = TRUE;
NotifyParent(DMM_MOVE);
_beginDrag = FALSE;
}
else
{
INT iItemSel = ::SendMessage(hwnd, TCM_GETCURSEL, 0, 0);
if ((_bTabTTHover == FALSE) && (iItem != iItemSel))
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = hwnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 1000;
_bTabTTHover = _TrackMouseEvent(&tme);
}
else
{
if (iItem == iItemSel)
{
toolTip.destroy();
_bTabTTHover = FALSE;
}
else if (iItem != _iLastHovered)
{
TCITEM tcItem = {0};
RECT rc = {0};
/* destroy old tooltip */
toolTip.destroy();
/* recalc mouse position */
::ClientToScreen(hwnd, &info.pt);
/* get text of toolbar */
tcItem.mask = TCIF_PARAM;
::SendMessage(hwnd, TCM_GETITEM, iItem, (LPARAM)&tcItem);
toolTip.init(_hInst, hwnd);
toolTip.Show(rc, ((tTbData*)tcItem.lParam)->pszName, info.pt.x, info.pt.y + 20);
}
}
/* save last hovered item */
_iLastHovered = iItem;
_beginDrag = FALSE;
}
return TRUE;
}
case WM_MOUSEHOVER:
{
INT iItem = 0;
TCITEM tcItem = {0};
RECT rc = {0};
TCHITTESTINFO info = {0};
/* get selected sub item */
info.pt.x = LOWORD(lParam);
info.pt.y = HIWORD(lParam);
iItem = ::SendMessage(hwnd, TCM_HITTEST, 0, (LPARAM)&info);
/* recalc mouse position */
::ClientToScreen(hwnd, &info.pt);
/* get text of toolbar */
tcItem.mask = TCIF_PARAM;
::SendMessage(hwnd, TCM_GETITEM, iItem, (LPARAM)&tcItem);
toolTip.init(_hInst, hwnd);
toolTip.Show(rc, ((tTbData*)tcItem.lParam)->pszName, info.pt.x, info.pt.y + 20);
return TRUE;
}
case WM_MOUSELEAVE:
{
toolTip.destroy();
_bTabTTHover = FALSE;
return TRUE;
}
case WM_NOTIFY:
{
LPNMHDR lpnmhdr = (LPNMHDR)lParam;
if ((lpnmhdr->hwndFrom == _hContTab) && (lpnmhdr->code == TCN_GETOBJECT))
{
INT iItem = 0;
TCHITTESTINFO info = {0};
/* get selected sub item */
info.pt.x = LOWORD(lParam);
info.pt.y = HIWORD(lParam);
iItem = ::SendMessage(hwnd, TCM_HITTEST, 0, (LPARAM)&info);
SelectTab(iItem);
}
break;
}
default:
break;
}
return ::CallWindowProc(_hDefaultTabProc, hwnd, Message, wParam, lParam);
}
void DockingCont::drawTabItem(DRAWITEMSTRUCT *pDrawItemStruct)
{
TCITEM tcItem = {0};
RECT rc = pDrawItemStruct->rcItem;
INT nTab = pDrawItemStruct->itemID;
bool isSelected = (nTab == getActiveTb());
/* get current selected item */
tcItem.mask = TCIF_PARAM;
::SendMessage(_hContTab, TCM_GETITEM, nTab, (LPARAM)&tcItem);
char* text = ((tTbData*)tcItem.lParam)->pszName;
INT length = strlen(((tTbData*)tcItem.lParam)->pszName);
/* get drawing context */
HDC hDc = pDrawItemStruct->hDC;
INT nSavedDC = ::SaveDC(hDc);
// For some bizarre reason the rcItem you get extends above the actual
// drawing area. We have to workaround this "feature".
rc.top += ::GetSystemMetrics(SM_CYEDGE);
::SetBkMode(hDc, TRANSPARENT);
HBRUSH hBrush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));
::FillRect(hDc, &rc, hBrush);
::DeleteObject((HGDIOBJ)hBrush);
/* draw orange bar */
if ((_bDrawOgLine == TRUE) && (isSelected))
{
RECT barRect = rc;
barRect.top += rc.bottom - 4;
hBrush = ::CreateSolidBrush(RGB(250, 170, 60));
::FillRect(hDc, &barRect, hBrush);
::DeleteObject((HGDIOBJ)hBrush);
}
/* draw icon if enabled */
if (((tTbData*)tcItem.lParam)->uMask & DWS_ICONTAB)
{
HIMAGELIST hImageList = (HIMAGELIST)::SendMessage(_hParent, DMM_GETIMAGELIST, 0, 0);
INT iPosImage = ::SendMessage(_hParent, DMM_GETICONPOS, 0, (LPARAM)((tTbData*)tcItem.lParam)->hClient);
if ((hImageList != NULL) && (iPosImage >= 0))
{
/* Get height of image so we */
IMAGEINFO info = {0};
RECT & imageRect = info.rcImage;
ImageList_GetImageInfo(hImageList, iPosImage, &info);
ImageList_Draw(hImageList, iPosImage, hDc, rc.left + 3, 2, ILD_NORMAL);
if (isSelected == true)
{
rc.left += imageRect.right - imageRect.left + 5;
}
}
}
if (isSelected == true)
{
COLORREF _unselectedColor = RGB(0, 0, 0);
::SetTextColor(hDc, _unselectedColor);
/* draw text */
rc.top -= ::GetSystemMetrics(SM_CYEDGE);
::SelectObject(hDc, _hFont);
::DrawText(hDc, text, length, &rc, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
}
::RestoreDC(hDc, nSavedDC);
}
/*********************************************************************************
* Process function of dialog
*/
BOOL CALLBACK DockingCont::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_NCACTIVATE:
{
/* Note: lParam to identify the trigger window */
if ((INT)lParam != -1)
{
::SendMessage(_hParent, WM_NCACTIVATE, wParam, 0);
}
break;
}
case WM_INITDIALOG:
{
_hContTab = ::GetDlgItem(_hSelf, IDC_TAB_CONT);
_hCaption = ::GetDlgItem(_hSelf, IDC_BTN_CAPTION);
/* intial subclassing of caption */
::SetWindowLong(_hCaption, GWL_USERDATA, reinterpret_cast<LONG>(this));
_hDefaultCaptionProc = reinterpret_cast<WNDPROC>(::SetWindowLong(_hCaption, GWL_WNDPROC, reinterpret_cast<LONG>(wndCaptionProc)));
/* intial subclassing of tab */
::SetWindowLong(_hContTab, GWL_USERDATA, reinterpret_cast<LONG>(this));
_hDefaultTabProc = reinterpret_cast<WNDPROC>(::SetWindowLong(_hContTab, GWL_WNDPROC, reinterpret_cast<LONG>(wndTabProc)));
/* set min tab width */
::SendMessage(_hContTab, TCM_SETMINTABWIDTH, 0, (LPARAM)MIN_TABWIDTH);
break;
}
case WM_NCCALCSIZE:
case WM_SIZE:
{
onSize();
break;
}
case WM_DRAWITEM :
{
/* draw tab or caption */
if (((DRAWITEMSTRUCT *)lParam)->CtlID == IDC_TAB_CONT)
{
drawTabItem((DRAWITEMSTRUCT *)lParam);
return TRUE;
}
else
{
drawCaptionItem((DRAWITEMSTRUCT *)lParam);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -