?? flattabctrl.h
字號:
/*
* Copyright (C) 2001-2003 Jacek Sieka, j_s@telia.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if !defined(AFX_FLATTABCTRL_H__FFFCBD5C_891D_44FB_B9F3_1DF83DA3EA83__INCLUDED_)
#define AFX_FLATTABCTRL_H__FFFCBD5C_891D_44FB_B9F3_1DF83DA3EA83__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../client/SettingsManager.h"
#define FT_BASE (WM_APP + 700)
/** This will be sent when the user presses a tab. WPARAM = HWND */
#define FTN_SELECTED (FT_BASE + 0)
/** The number of rows changed */
#define FTN_ROWS_CHANGED (FT_BASE + 2)
/** Set currently active tab to the HWND pointed by WPARAM */
#define FTM_SETACTIVE (FT_BASE + 1)
#define IDC_SELECT_WINDOW 6000
template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits>
class ATL_NO_VTABLE FlatTabCtrlImpl : public CWindowImpl< T, TBase, TWinTraits> {
public:
enum { FT_EXTRA_SPACE = 18 };
FlatTabCtrlImpl() : closing(NULL), rows(1), height(0), active(NULL) {
black.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
};
~FlatTabCtrlImpl() { }
static LPCTSTR GetWndClassName()
{
return _T("FlatTabCtrl");
}
void addTab(HWND hWnd, COLORREF color = RGB(0, 0, 0)) {
TabInfo* i = new TabInfo(hWnd, color);
dcassert(getTabInfo(hWnd) == NULL);
tabs.push_back(i);
active = i;
calcRows(false);
Invalidate();
}
void removeTab(HWND aWnd) {
TabInfo::ListIter i;
for(i = tabs.begin(); i != tabs.end(); ++i) {
if((*i)->hWnd == aWnd)
break;
}
dcassert(i != tabs.end());
TabInfo* ti = *i;
if(active == ti)
active = NULL;
delete ti;
tabs.erase(i);
calcRows(false);
Invalidate();
}
void setActive(HWND aWnd) {
TabInfo* ti = getTabInfo(aWnd);
dcassert(ti != NULL);
active = ti;
ti->dirty = false;
calcRows(false);
Invalidate();
}
void setDirty(HWND aWnd) {
TabInfo* ti = getTabInfo(aWnd);
dcassert(ti != NULL);
bool inval = ti->update();
if(active != ti) {
if(!ti->dirty) {
ti->dirty = true;
inval = true;
}
}
if(inval) {
calcRows(false);
Invalidate();
}
}
void setColor(HWND aWnd, COLORREF color) {
TabInfo* ti = getTabInfo(aWnd);
if(ti != NULL) {
ti->pen.DeleteObject();
ti->pen.CreatePen(PS_SOLID, 1, color);
Invalidate();
}
}
void updateText(HWND aWnd, LPCTSTR text) {
TabInfo* ti = getTabInfo(aWnd);
if(ti != NULL) {
ti->updateText(text);
calcRows(false);
Invalidate();
}
}
BEGIN_MSG_MAP(thisClass)
MESSAGE_HANDLER(WM_SIZE, onSize)
MESSAGE_HANDLER(WM_CREATE, onCreate)
MESSAGE_HANDLER(WM_PAINT, onPaint)
MESSAGE_HANDLER(WM_LBUTTONDOWN, onLButtonDown)
MESSAGE_HANDLER(WM_CONTEXTMENU, onContextMenu)
COMMAND_ID_HANDLER(IDC_CLOSE_WINDOW, onCloseWindow)
COMMAND_ID_HANDLER(IDC_CHEVRON, onChevron)
COMMAND_RANGE_HANDLER(IDC_SELECT_WINDOW, IDC_SELECT_WINDOW+tabs.size(), onSelectWindow)
END_MSG_MAP()
LRESULT onLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) {
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
int row = getRows() - ((yPos / getTabHeight()) + 1);
for(TabInfo::ListIter i = tabs.begin(); i != tabs.end(); ++i) {
TabInfo* t = *i;
if((row == t->row) && (xPos >= t->xpos) && (xPos < (t->xpos + t->getWidth())) ) {
// Bingo, this was clicked
HWND hWnd = GetParent();
if(hWnd) {
::SendMessage(hWnd, FTN_SELECTED, (WPARAM)t->hWnd, 0);
}
break;
}
}
return 0;
}
LRESULT onContextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) {
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; // location of mouse click
ScreenToClient(&pt);
int xPos = pt.x;
int row = getRows() - ((pt.y / getTabHeight()) + 1);
for(TabInfo::ListIter i = tabs.begin(); i != tabs.end(); ++i) {
TabInfo* t = *i;
if((row == t->row) && (xPos >= t->xpos) && (xPos < (t->xpos + t->getWidth())) ) {
// Bingo, this was clicked
closing = t->hWnd;
ClientToScreen(&pt);
CMenu mnu;
mnu.CreatePopupMenu();
mnu.AppendMenu(MF_STRING, IDC_CLOSE_WINDOW, CSTRING(CLOSE));
mnu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, m_hWnd);
break;
}
}
return 0;
}
LRESULT onCloseWindow(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
::SendMessage(closing, WM_CLOSE, 0, 0);
return 0;
}
int getTabHeight() { return height; };
int getHeight() { return (getRows() * getTabHeight())+1; };
int getFill() { return (getTabHeight() + 1) / 2; };
int getRows() { return rows; };
void calcRows(bool inval = true) {
CRect rc;
GetClientRect(rc);
int r = 1;
int w = 0;
bool notify = false;
bool needInval = false;
for(TabInfo::ListIter i = tabs.begin(); i != tabs.end(); ++i) {
TabInfo* ti = *i;
if( (r != 0) && ((w + ti->getWidth() + getFill()) > rc.Width()) ) {
if(r >= SETTING(MAX_TAB_ROWS)) {
notify |= (rows != r);
rows = r;
r = 0;
chevron.EnableWindow(TRUE);
} else {
r++;
w = 0;
}
}
ti->xpos = w;
needInval |= (ti->row != (r-1));
ti->row = r-1;
w += ti->getWidth();
}
if(r != 0) {
chevron.EnableWindow(FALSE);
notify |= (rows != r);
rows = r;
}
if(notify) {
::SendMessage(GetParent(), FTN_ROWS_CHANGED, 0, 0);
}
if(needInval && inval)
Invalidate();
}
LRESULT onCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
chevron.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
BS_PUSHBUTTON , 0, IDC_CHEVRON);
chevron.SetWindowText("
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -