📄 windowsdlg.cpp
字号:
_winMgr.InitToFitSizeFromCurrent(_hSelf);
// save min size for OK/Cancel buttons
_szMinButton = RectToSize(_winMgr.GetRect(IDOK));
_szMinListCtrl = RectToSize(_winMgr.GetRect(IDC_WINDOWS_LIST));
_lastSort = -1;
_winMgr.CalcLayout(_hSelf);
_winMgr.SetWindowPositions(_hSelf);
getClientRect(_rc);
_hList = ::GetDlgItem(_hSelf, IDC_WINDOWS_LIST);
DWORD exStyle = ListView_GetExtendedListViewStyle(_hList);
exStyle |= LVS_EX_HEADERDRAGDROP|LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER;
ListView_SetExtendedListViewStyle(_hList, exStyle);
RECT rc;
GetClientRect(_hList, &rc);
LONG width = rc.right - rc.left;
LVCOLUMN lvColumn;
memset(&lvColumn, 0, sizeof(lvColumn));
lvColumn.mask = LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM|LVCF_FMT;
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.pszText = TEXT("Name");
lvColumn.cx = width/4;
SendMessage(_hList, LVM_INSERTCOLUMN, 0, LPARAM(&lvColumn));
lvColumn.pszText = TEXT("Path");
lvColumn.cx = 300;
SendMessage(_hList, LVM_INSERTCOLUMN, 1, LPARAM(&lvColumn));
lvColumn.fmt = LVCFMT_CENTER;
lvColumn.pszText = TEXT("Type");
lvColumn.cx = 40;
SendMessage(_hList, LVM_INSERTCOLUMN, 2, LPARAM(&lvColumn));
fitColumnsToSize();
if (_lastKnownLocation.bottom > 0 && _lastKnownLocation.right > 0)
{
SetWindowPos(_hSelf, NULL, _lastKnownLocation.left, _lastKnownLocation.top,
_lastKnownLocation.right-_lastKnownLocation.left, _lastKnownLocation.bottom-_lastKnownLocation.top, SWP_SHOWWINDOW);
}
else
{
goToCenter();
}
doRefresh(true);
return TRUE;
}
void WindowsDlg::onSize(UINT nType, int cx, int cy)
{
MyBaseClass::onSize(nType, cx, cy);
fitColumnsToSize();
}
void WindowsDlg::onGetMinMaxInfo(MINMAXINFO* lpMMI)
{
MyBaseClass::onGetMinMaxInfo(lpMMI);
}
LRESULT WindowsDlg::onWinMgr(WPARAM wp, LPARAM lp)
{
NMWINMGR &nmw = *(NMWINMGR *)lp;
if (nmw.code==NMWINMGR::GET_SIZEINFO) {
switch(wp)
{
case IDOK:
case IDCANCEL:
case IDC_WINDOWS_SAVE:
case IDC_WINDOWS_CLOSE:
case IDC_WINDOWS_SORT:
nmw.sizeinfo.szMin = _szMinButton;
nmw.processed = TRUE;
return TRUE;
case IDC_WINDOWS_LIST:
nmw.sizeinfo.szMin = _szMinListCtrl;
nmw.processed = TRUE;
return TRUE;
}
}
return MyBaseClass::onWinMgr(wp, lp);
}
void WindowsDlg::doRefresh(bool invalidate /*= false*/)
{
if (_hSelf != NULL && isVisible())
{
if (_hList != NULL)
{
size_t count = (_pTab != NULL) ? _pTab->nbItem() : 0;
size_t oldSize = _idxMap.size();
if (!invalidate && count == oldSize)
return;
if (count != oldSize)
{
size_t lo = 0;
_idxMap.resize(count);
if (oldSize < count)
lo = oldSize;
for (size_t i=lo; i<count; ++i)
_idxMap[i] = i;
}
LPARAM lp = invalidate ? LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL : LVSICF_NOSCROLL;
//ListView_SetItemCountEx(_hList, count, lp);
::SendMessage(_hList, LVM_SETITEMCOUNT, (WPARAM)count, lp);
::InvalidateRect(_hList, &_rc, FALSE);
resetSelection();
updateButtonState();
}
}
}
void WindowsDlg::fitColumnsToSize()
{
// perhaps make the path column auto size
RECT rc;
if (GetClientRect(_hList, &rc))
{
int len = (rc.right - rc.left);
len -= (int)SendMessage(_hList, LVM_GETCOLUMNWIDTH, 0, 0);
len -= (int)SendMessage(_hList, LVM_GETCOLUMNWIDTH, 2, 0);
len -= GetSystemMetrics(SM_CXVSCROLL);
len -= 1;
SendMessage(_hList, LVM_SETCOLUMNWIDTH, 1, len);
}
}
void WindowsDlg::resetSelection()
{
int curSel = _pTab->getCurrentTabIndex();
int pos = 0;
for (vector<int>::iterator itr = _idxMap.begin(), end = _idxMap.end(); itr != end; ++itr, ++pos)
{
if (*itr == curSel)
{
ListView_SetItemState(_hList, pos, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED)
}
else
{
ListView_SetItemState(_hList, pos, 0, LVIS_SELECTED);
}
}
}
void WindowsDlg::doSave()
{
NMWINDLG nmdlg;
nmdlg.type = WDT_SAVE;
nmdlg.curSel = ListView_GetNextItem(_hList, -1, LVNI_SELECTED);
nmdlg.hwndFrom = _hSelf;
nmdlg.code = WDN_NOTIFY;
nmdlg.nItems = ListView_GetSelectedCount(_hList);
nmdlg.Items = new UINT[nmdlg.nItems];
for (UINT i=-1, j=0;;++j) {
i = ListView_GetNextItem(_hList, i, LVNI_SELECTED);
if (i == -1) break;
nmdlg.Items[j] = _idxMap[i];
}
SendMessage(_hParent, WDN_NOTIFY, 0, LPARAM(&nmdlg));
delete[] nmdlg.Items;
::InvalidateRect(_hList, &_rc, FALSE);
ListView_RedrawItems(_hList, 0, ListView_GetSelectedCount(_hList));
}
void WindowsDlg::destroy()
{
::GetWindowRect(_hSelf, &_lastKnownLocation);
HWND hSelf = _hSelf;
_hSelf = NULL;
::DestroyWindow(hSelf);
}
void WindowsDlg::activateCurrent()
{
if (ListView_GetSelectedCount(_hList) == 1)
{
NMWINDLG nmdlg;
nmdlg.type = WDT_ACTIVATE;
//nmdlg.curSel = ListView_GetNextItem(_hList, -1, LVNI_ALL|LVNI_SELECTED);
nmdlg.curSel = _idxMap[ListView_GetNextItem(_hList, -1, LVNI_ALL|LVNI_SELECTED)];
nmdlg.hwndFrom = _hSelf;
nmdlg.code = WDN_NOTIFY;
SendMessage(_hParent, WDN_NOTIFY, 0, LPARAM(&nmdlg));
::GetWindowRect(_hSelf, &_lastKnownLocation);
EndDialog(_hSelf, IDOK);
}
}
void WindowsDlg::doClose()
{
NMWINDLG nmdlg;
nmdlg.type = WDT_CLOSE;
//nmdlg.curSel = ListView_GetNextItem(_hList, -1, LVNI_SELECTED);
int index = ListView_GetNextItem(_hList, -1, LVNI_ALL|LVNI_SELECTED);
if (index == -1) return;
nmdlg.curSel = _idxMap[index];
nmdlg.hwndFrom = _hSelf;
nmdlg.code = WDN_NOTIFY;
UINT n = nmdlg.nItems = ListView_GetSelectedCount(_hList);
nmdlg.Items = new UINT[nmdlg.nItems];
vector<int> key;
key.resize(n, 0x7fffffff);
for(UINT i=-1, j=0;; ++j) {
i = ListView_GetNextItem(_hList, i, LVNI_SELECTED);
if (i == -1) break;
ListView_SetItemState(_hList, i, 0, LVIS_SELECTED); // deselect
nmdlg.Items[j] = _idxMap[i];
key[j] = i;
}
SendMessage(_hParent, WDN_NOTIFY, 0, LPARAM(&nmdlg));
if (nmdlg.processed)
{
// Trying to retain sort order. fairly sure there is a much better algorithm for this
vector<int>::iterator kitr = key.begin();
for (UINT i=0; i<n; ++i, ++kitr)
{
if (nmdlg.Items[i] == -1)
{
int oldVal = _idxMap[*kitr];
_idxMap[*kitr] = -1;
for (vector<int>::iterator itr = _idxMap.begin(), end = _idxMap.end(); itr != end; ++itr)
if (*itr > oldVal)
--(*itr);
}
}
_idxMap.erase(std::remove_if(_idxMap.begin(), _idxMap.end(), bind2nd(equal_to<int>(), -1)), _idxMap.end());
}
delete[] nmdlg.Items;
if (_pTab->nbItem() != _idxMap.size())
doRefresh(true);
else
{
// select first previously selected item (or last one if only the last one was removed)
if (index == _idxMap.size()) index --;
if (index >= 0)
{
ListView_SetItemState(_hList, index, LVIS_SELECTED, LVIS_SELECTED);
ListView_RedrawItems(_hList, 0, _idxMap.size() - 1);
}
ListView_SetItemCount(_hList, _idxMap.size());
}
}
void WindowsDlg::doSortToTabs()
{
int curSel = ListView_GetNextItem(_hList, -1, LVNI_SELECTED);
if (curSel == -1)
curSel = 0;
NMWINDLG nmdlg;
nmdlg.type = WDT_SORT;
nmdlg.hwndFrom = _hSelf;
//nmdlg.curSel = curSel;
nmdlg.curSel = _idxMap[curSel];
nmdlg.code = WDN_NOTIFY;
UINT n = nmdlg.nItems = ListView_GetItemCount(_hList);
nmdlg.Items = new UINT[nmdlg.nItems];
vector<int> key;
key.resize(n, 0x7fffffff);
for(UINT i=-1, j=0;; ++j) {
i = ListView_GetNextItem(_hList, i, LVNI_ALL);
if (i == -1) break;
nmdlg.Items[j] = _idxMap[i];
if (i == curSel)
nmdlg.curSel = j;
key[j] = i;
}
SendMessage(_hParent, WDN_NOTIFY, 0, LPARAM(&nmdlg));
if (nmdlg.processed)
{
_idxMap.clear();
doRefresh(true);
}
delete[] nmdlg.Items;
}
WindowsMenu::WindowsMenu()
{}
WindowsMenu::~WindowsMenu()
{
if (_hMenu)
DestroyMenu(_hMenu);
}
void WindowsMenu::init(HINSTANCE hInst, HMENU hMainMenu, const TCHAR *translation)
{
_hMenu = ::LoadMenu(hInst, MAKEINTRESOURCE(IDR_WINDOWS_MENU));
if (translation && translation[0])
{
generic_string windowStr(translation);
windowStr += TEXT("...");
::ModifyMenu(_hMenu, IDM_WINDOW_WINDOWS, MF_BYCOMMAND, IDM_WINDOW_WINDOWS, windowStr.c_str());
}
UINT pos = 0;
for(pos = GetMenuItemCount(hMainMenu) - 1; pos > 0; --pos)
{
if ((GetMenuState(hMainMenu, pos, MF_BYPOSITION) & MF_POPUP) != MF_POPUP)
continue;
break;
}
MENUITEMINFO mii;
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING|MIIM_SUBMENU;
TCHAR buffer[32];
LoadString(hInst, IDR_WINDOWS_MENU, buffer, 32);
mii.dwTypeData = (TCHAR *)((translation && translation[0])?translation:buffer);
mii.hSubMenu = _hMenu;
InsertMenuItem(hMainMenu, pos, TRUE, &mii);
}
void WindowsMenu::initPopupMenu(HMENU hMenu, DocTabView *pTab)
{
if (hMenu == _hMenu)
{
int curDoc = pTab->getCurrentTabIndex();
int nMaxDoc = IDM_WINDOW_MRU_LIMIT - IDM_WINDOW_MRU_FIRST + 1;
int nDoc = pTab->nbItem();
nDoc = min(nDoc, nMaxDoc);
int id, pos;
for (id=IDM_WINDOW_MRU_FIRST, pos=0; id<IDM_WINDOW_MRU_FIRST + nDoc; ++id, ++pos)
{
TCHAR buffer[MAX_PATH];
BufferID bufID = pTab->getBufferByIndex(pos);
Buffer * buf = MainFileManager->getBufferByID(bufID);
MENUITEMINFO mii;
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING|MIIM_STATE|MIIM_ID;
mii.dwTypeData = buildFileName(buffer, 60, pos, buf->getFileName());
mii.fState &= ~(MF_GRAYED|MF_DISABLED|MF_CHECKED);
if (pos == curDoc)
mii.fState |= MF_CHECKED;
mii.wID = id;
UINT state = GetMenuState(hMenu, id, MF_BYCOMMAND);
if (state == -1)
InsertMenuItem(hMenu, IDM_WINDOW_WINDOWS, FALSE, &mii);
else
SetMenuItemInfo(hMenu, id, FALSE, &mii);
}
for ( ; id<=IDM_WINDOW_MRU_LIMIT; ++id)
{
DeleteMenu(hMenu, id, FALSE);
}
}
}
/*
void WindowsMenu::uninitPopupMenu(HMENU hMenu, ScintillaEditView *pView)
{
if (hMenu == _hMenu)
{
}
}
*/
static TCHAR* convertFileName(TCHAR *buffer, const TCHAR *filename)
{
TCHAR *b = buffer;
const TCHAR *p = filename;
while (*p)
{
if (*p == '&') *b++ = '&';
*b++ = *p++;
}
*b = 0;
return buffer;
}
TCHAR *WindowsMenu::buildFileName(TCHAR *buffer, int len, int pos, const TCHAR *filename)
{
TCHAR cwd[MAX_PATH];
buffer[0] = 0;
GetCurrentDirectory(_countof(cwd), cwd);
lstrcat(cwd, TEXT("\\"));
TCHAR *itr = buffer;
TCHAR *end = buffer + len - 1;
if (pos < 9)
{
*itr++ = '&';
*itr++ = '1' + pos;
}
else if (pos == 9)
{
*itr++ = '1';
*itr++ = '&';
*itr++ = '0';
}
else
{
wsprintf(itr, TEXT("%d"), pos+1);
itr = itr + lstrlen(itr);
}
*itr++ = ':';
*itr++ = ' ';
if (0 == generic_strnicmp(filename, cwd, lstrlen(cwd)))
{
TCHAR cnvName[MAX_PATH];
const TCHAR *s1 = PathFindFileName(filename);
int len = lstrlen(s1);
if (len < (end-itr))
{
lstrcpy(cnvName, s1);
}
else
{
int n = (len-3-(itr-buffer))/2;
generic_strncpy(cnvName, s1, n);
lstrcpy(cnvName+n, TEXT("..."));
lstrcat(cnvName, s1 + lstrlen(s1) - n);
}
convertFileName(itr, cnvName);
}
else
{
TCHAR cnvName[MAX_PATH*2];
const TCHAR *s1 = convertFileName(cnvName, filename);
PathCompactPathEx(itr, filename, len - (itr-buffer), 0);
}
return buffer;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -