📄 windowsdlg.cpp
字号:
_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 = "Name";
lvColumn.cx = width/4;
SendMessage(_hList, LVM_INSERTCOLUMN, 0, LPARAM(&lvColumn));
lvColumn.pszText = "Path";
lvColumn.cx = 300;
SendMessage(_hList, LVM_INSERTCOLUMN, 1, LPARAM(&lvColumn));
lvColumn.fmt = LVCFMT_CENTER;
lvColumn.pszText = "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 = (_pView != NULL) ? _pView->getNbDoc() : 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 = _pView->getCurrentDocIndex();
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;
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 (_pView->getNbDoc() != _idxMap.size())
doRefresh(true);
else
{
ListView_RedrawItems(_hList, 0, ListView_GetSelectedCount(_hList));
ListView_SetItemCount(_hList, _idxMap.size());
}
}
void WindowsDlg::doSortToTabs()
{
int curSel = ListView_GetNextItem(_hList, -1, LVNI_SELECTED);
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 char *translation)
{
_hMenu = ::LoadMenu(hInst, MAKEINTRESOURCE(IDR_WINDOWS_MENU));
if (translation && translation[0])
{
string windowStr(translation);
windowStr += "...";
::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;
char buffer[32];
LoadString(hInst, IDR_WINDOWS_MENU, buffer, 32);
mii.dwTypeData = (LPSTR)((translation && translation[0])?translation:buffer);
mii.hSubMenu = _hMenu;
InsertMenuItem(hMainMenu, pos, TRUE, &mii);
}
void WindowsMenu::initPopupMenu(HMENU hMenu, ScintillaEditView *pView)
{
if (hMenu == _hMenu)
{
int curDoc = pView->getCurrentDocIndex();
int nMaxDoc = IDM_WINDOW_MRU_LIMIT - IDM_WINDOW_MRU_FIRST + 1;
int nDoc = pView->getNbDoc();
nDoc = min(nDoc, nMaxDoc);
int id, pos;
for (id=IDM_WINDOW_MRU_FIRST, pos=0; id<IDM_WINDOW_MRU_FIRST + nDoc; ++id, ++pos)
{
char buffer[MAX_PATH];
const Buffer& scbuf = pView->getBufferAt(pos);
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, scbuf.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 char* convertFileName(char *buffer, const char *filename)
{
char *b = buffer;
const char *p = filename;
while (*p)
{
if (*p == '&') *b++ = '&';
*b++ = *p++;
}
*b = 0;
return buffer;
}
char *WindowsMenu::buildFileName(char *buffer, int len, int pos, const char *filename)
{
char cwd[MAX_PATH];
buffer[0] = 0;
GetCurrentDirectory(_countof(cwd), cwd);
strcat(cwd, "\\");
char *itr = buffer;
char *end = buffer + len - 1;
if (pos < 9)
{
*itr++ = '&';
*itr++ = '1' + pos;
}
else if (pos == 9)
{
*itr++ = '1';
*itr++ = '&';
*itr++ = '0';
}
else
{
itr = itoa(pos+1, itr, 10) + strlen(itr);
}
*itr++ = ':';
*itr++ = ' ';
if (0 == strnicmp(filename, cwd, strlen(cwd)))
{
char cnvName[MAX_PATH];
const char *s1 = PathFindFileName(filename);
int len = strlen(s1);
if (len < (end-itr))
{
strcpy(cnvName, s1);
}
else
{
int n = (len-3-(itr-buffer))/2;
strncpy(cnvName, s1, n);
strcpy(cnvName+n, "...");
strcat(cnvName, s1 + strlen(s1) - n);
}
convertFileName(itr, cnvName);
}
else
{
char cnvName[MAX_PATH*2];
const char *s1 = convertFileName(cnvName, filename);
PathCompactPathEx(itr, filename, len - (itr-buffer), 0);
}
return buffer;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -