[NEW] (Author: Pavel Nedev) Add notification for plugins : NPPN_BEFORESHUTDOWN NPPN_CANCELSHUTDOWN NPPN_FILEBEFORERENAME NPPN_FILERENAMECANCEL NPPN_FILERENAMED NPPN_FILEBEFOREDELETE NPPN_FILEDELETEFAILED NPPN_FILEDELETED
git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1346 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
parent
d9299e644f
commit
f224c673bf
@ -541,4 +541,44 @@ enum winVer{WV_UNKNOWN, WV_WIN32S, WV_95, WV_98, WV_ME, WV_NT, WV_W2K, WV_XP, WV
|
||||
//scnNotification->nmhdr.hwndFrom = NULL;
|
||||
//scnNotification->nmhdr.idFrom = BufferID;
|
||||
|
||||
#define NPPN_BEFORESHUTDOWN (NPPN_FIRST + 19) // To notify plugins that Npp shutdown has been triggered, files have not been closed yet
|
||||
//scnNotification->nmhdr.code = NPPN_BEFORESHUTDOWN;
|
||||
//scnNotification->nmhdr.hwndFrom = hwndNpp;
|
||||
//scnNotification->nmhdr.idFrom = 0;
|
||||
|
||||
#define NPPN_CANCELSHUTDOWN (NPPN_FIRST + 20) // To notify plugins that Npp shutdown has been cancelled
|
||||
//scnNotification->nmhdr.code = NPPN_CANCELSHUTDOWN;
|
||||
//scnNotification->nmhdr.hwndFrom = hwndNpp;
|
||||
//scnNotification->nmhdr.idFrom = 0;
|
||||
|
||||
#define NPPN_FILEBEFORERENAME (NPPN_FIRST + 21) // To notify plugins that file is to be renamed
|
||||
//scnNotification->nmhdr.code = NPPN_FILEBEFORERENAME;
|
||||
//scnNotification->nmhdr.hwndFrom = hwndNpp;
|
||||
//scnNotification->nmhdr.idFrom = BufferID;
|
||||
|
||||
#define NPPN_FILERENAMECANCEL (NPPN_FIRST + 22) // To notify plugins that file rename has been cancelled
|
||||
//scnNotification->nmhdr.code = NPPN_FILERENAMECANCEL;
|
||||
//scnNotification->nmhdr.hwndFrom = hwndNpp;
|
||||
//scnNotification->nmhdr.idFrom = BufferID;
|
||||
|
||||
#define NPPN_FILERENAMED (NPPN_FIRST + 23) // To notify plugins that file has been renamed
|
||||
//scnNotification->nmhdr.code = NPPN_FILERENAMED;
|
||||
//scnNotification->nmhdr.hwndFrom = hwndNpp;
|
||||
//scnNotification->nmhdr.idFrom = BufferID;
|
||||
|
||||
#define NPPN_FILEBEFOREDELETE (NPPN_FIRST + 24) // To notify plugins that file is to be deleted
|
||||
//scnNotification->nmhdr.code = NPPN_FILEBEFOREDELETE;
|
||||
//scnNotification->nmhdr.hwndFrom = hwndNpp;
|
||||
//scnNotification->nmhdr.idFrom = BufferID;
|
||||
|
||||
#define NPPN_FILEDELETEFAILED (NPPN_FIRST + 25) // To notify plugins that file deletion has failed
|
||||
//scnNotification->nmhdr.code = NPPN_FILEDELETEFAILED;
|
||||
//scnNotification->nmhdr.hwndFrom = hwndNpp;
|
||||
//scnNotification->nmhdr.idFrom = BufferID;
|
||||
|
||||
#define NPPN_FILEDELETED (NPPN_FIRST + 26) // To notify plugins that file has been deleted
|
||||
//scnNotification->nmhdr.code = NPPN_FILEDELETED;
|
||||
//scnNotification->nmhdr.hwndFrom = hwndNpp;
|
||||
//scnNotification->nmhdr.idFrom = BufferID;
|
||||
|
||||
#endif //NOTEPAD_PLUS_MSGS_H
|
||||
|
@ -400,7 +400,7 @@ void PluginsManager::runPluginCommand(const TCHAR *pluginName, int commandID)
|
||||
}
|
||||
}
|
||||
|
||||
void PluginsManager::notify(SCNotification *notification)
|
||||
void PluginsManager::notify(const SCNotification *notification)
|
||||
{
|
||||
for (size_t i = 0, len = _pluginInfos.size() ; i < len ; ++i)
|
||||
{
|
||||
|
@ -109,7 +109,7 @@ public:
|
||||
HMENU setMenu(HMENU hMenu, const TCHAR *menuName);
|
||||
bool getShortcutByCmdID(int cmdID, ShortcutKey *sk);
|
||||
|
||||
void notify(SCNotification *notification);
|
||||
void notify(const SCNotification *notification);
|
||||
void relayNppMessages(UINT Message, WPARAM wParam, LPARAM lParam);
|
||||
bool relayPluginMessages(UINT Message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
@ -1449,21 +1449,21 @@ bool Notepad_plus::replaceInFiles()
|
||||
|
||||
getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir);
|
||||
|
||||
CProgress progress;
|
||||
size_t filesCount = fileNames.size();
|
||||
size_t filesPerPercent = 1;
|
||||
|
||||
if (filesCount > 1)
|
||||
{
|
||||
if (filesCount >= 200)
|
||||
filesPerPercent = filesCount / 100;
|
||||
progress.Open(NULL, TEXT("Replace In Files progress..."));
|
||||
}
|
||||
|
||||
for (size_t i = 0, updateOnCount = filesPerPercent; i < filesCount; ++i)
|
||||
{
|
||||
if (progress.IsCancelled()) break;
|
||||
|
||||
CProgress progress;
|
||||
size_t filesCount = fileNames.size();
|
||||
size_t filesPerPercent = 1;
|
||||
|
||||
if (filesCount > 1)
|
||||
{
|
||||
if (filesCount >= 200)
|
||||
filesPerPercent = filesCount / 100;
|
||||
progress.Open(NULL, TEXT("Replace In Files progress..."));
|
||||
}
|
||||
|
||||
for (size_t i = 0, updateOnCount = filesPerPercent; i < filesCount; ++i)
|
||||
{
|
||||
if (progress.IsCancelled()) break;
|
||||
|
||||
bool closeBuf = false;
|
||||
|
||||
BufferID id = MainFileManager->getBufferFromName(fileNames.at(i).c_str());
|
||||
@ -1491,10 +1491,10 @@ bool Notepad_plus::replaceInFiles()
|
||||
if (closeBuf)
|
||||
MainFileManager->closeBuffer(id, _pEditView);
|
||||
}
|
||||
if (i == updateOnCount)
|
||||
{
|
||||
updateOnCount += filesPerPercent;
|
||||
progress.SetPercent((i * 100) / filesCount, fileNames.at(i).c_str());
|
||||
if (i == updateOnCount)
|
||||
{
|
||||
updateOnCount += filesPerPercent;
|
||||
progress.SetPercent((i * 100) / filesCount, fileNames.at(i).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1539,21 +1539,21 @@ bool Notepad_plus::findInFiles()
|
||||
|
||||
_findReplaceDlg.beginNewFilesSearch();
|
||||
|
||||
CProgress progress;
|
||||
size_t filesCount = fileNames.size();
|
||||
size_t filesPerPercent = 1;
|
||||
|
||||
if (filesCount > 1)
|
||||
{
|
||||
if (filesCount >= 200)
|
||||
filesPerPercent = filesCount / 100;
|
||||
progress.Open(NULL, TEXT("Find In Files progress..."));
|
||||
}
|
||||
|
||||
CProgress progress;
|
||||
size_t filesCount = fileNames.size();
|
||||
size_t filesPerPercent = 1;
|
||||
|
||||
if (filesCount > 1)
|
||||
{
|
||||
if (filesCount >= 200)
|
||||
filesPerPercent = filesCount / 100;
|
||||
progress.Open(NULL, TEXT("Find In Files progress..."));
|
||||
}
|
||||
|
||||
for (size_t i = 0, updateOnCount = filesPerPercent; i < filesCount; ++i)
|
||||
{
|
||||
if (progress.IsCancelled()) break;
|
||||
|
||||
if (progress.IsCancelled()) break;
|
||||
|
||||
bool closeBuf = false;
|
||||
BufferID id = MainFileManager->getBufferFromName(fileNames.at(i).c_str());
|
||||
if (id == BUFFER_INVALID)
|
||||
@ -1573,10 +1573,10 @@ bool Notepad_plus::findInFiles()
|
||||
if (closeBuf)
|
||||
MainFileManager->closeBuffer(id, _pEditView);
|
||||
}
|
||||
if (i == updateOnCount)
|
||||
{
|
||||
updateOnCount += filesPerPercent;
|
||||
progress.SetPercent((i * 100) / filesCount, fileNames.at(i).c_str());
|
||||
if (i == updateOnCount)
|
||||
{
|
||||
updateOnCount += filesPerPercent;
|
||||
progress.SetPercent((i * 100) / filesCount, fileNames.at(i).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -4688,6 +4688,12 @@ void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask)
|
||||
}
|
||||
case DOC_DELETED: //ask for keep
|
||||
{
|
||||
SCNotification scnN;
|
||||
scnN.nmhdr.code = NPPN_FILEDELETED;
|
||||
scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf();
|
||||
scnN.nmhdr.idFrom = (uptr_t)buffer->getID();
|
||||
_pluginsManager.notify(&scnN);
|
||||
|
||||
int index = _pDocTab->getIndexByBuffer(buffer->getID());
|
||||
int iView = currentView();
|
||||
if (index == -1)
|
||||
|
@ -1489,6 +1489,12 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
|
||||
}
|
||||
else
|
||||
{
|
||||
SCNotification scnN;
|
||||
scnN.nmhdr.code = NPPN_BEFORESHUTDOWN;
|
||||
scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf();
|
||||
scnN.nmhdr.idFrom = 0;
|
||||
_pluginsManager.notify(&scnN);
|
||||
|
||||
if (_pTrayIco)
|
||||
_pTrayIco->doTrayIcon(REMOVE);
|
||||
|
||||
@ -1516,6 +1522,9 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
|
||||
if (!allClosed)
|
||||
{
|
||||
//User cancelled the shutdown
|
||||
scnN.nmhdr.code = NPPN_CANCELSHUTDOWN;
|
||||
_pluginsManager.notify(&scnN);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1527,10 +1536,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
|
||||
if (_configStyleDlg.isCreated() && ::IsWindowVisible(_configStyleDlg.getHSelf()))
|
||||
_configStyleDlg.restoreGlobalOverrideValues();
|
||||
|
||||
SCNotification scnN;
|
||||
scnN.nmhdr.code = NPPN_SHUTDOWN;
|
||||
scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf();
|
||||
scnN.nmhdr.idFrom = 0;
|
||||
_pluginsManager.notify(&scnN);
|
||||
|
||||
saveFindHistory(); //writeFindHistory
|
||||
|
@ -1085,6 +1085,12 @@ bool Notepad_plus::fileRename(BufferID id)
|
||||
bufferID = _pEditView->getCurrentBufferID();
|
||||
Buffer * buf = MainFileManager->getBufferByID(bufferID);
|
||||
|
||||
SCNotification scnN;
|
||||
scnN.nmhdr.code = NPPN_FILEBEFORERENAME;
|
||||
scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf();
|
||||
scnN.nmhdr.idFrom = (uptr_t)bufferID;
|
||||
_pluginsManager.notify(&scnN);
|
||||
|
||||
FileDialog fDlg(_pPublicInterface->getHSelf(), _pPublicInterface->getHinst());
|
||||
|
||||
fDlg.setExtFilter(TEXT("All types"), TEXT(".*"), NULL);
|
||||
@ -1093,11 +1099,14 @@ bool Notepad_plus::fileRename(BufferID id)
|
||||
fDlg.setDefFileName(buf->getFileName());
|
||||
TCHAR *pfn = fDlg.doSaveDlg();
|
||||
|
||||
bool success = false;
|
||||
if (pfn)
|
||||
{
|
||||
MainFileManager->moveFile(bufferID, pfn);
|
||||
}
|
||||
return false;
|
||||
success = MainFileManager->moveFile(bufferID, pfn);
|
||||
|
||||
scnN.nmhdr.code = success ? NPPN_FILERENAMED : NPPN_FILERENAMECANCEL;
|
||||
_pluginsManager.notify(&scnN);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@ -1120,6 +1129,12 @@ bool Notepad_plus::fileDelete(BufferID id)
|
||||
|
||||
if (goAhead)
|
||||
{
|
||||
SCNotification scnN;
|
||||
scnN.nmhdr.code = NPPN_FILEBEFOREDELETE;
|
||||
scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf();
|
||||
scnN.nmhdr.idFrom = (uptr_t)bufferID;
|
||||
_pluginsManager.notify(&scnN);
|
||||
|
||||
if (!MainFileManager->deleteFile(bufferID))
|
||||
{
|
||||
_nativeLangSpeaker.messageBox("DeleteFileFailed",
|
||||
@ -1127,11 +1142,20 @@ bool Notepad_plus::fileDelete(BufferID id)
|
||||
TEXT("Delete File failed"),
|
||||
TEXT("Delete File"),
|
||||
MB_OK);
|
||||
|
||||
scnN.nmhdr.code = NPPN_FILEDELETEFAILED;
|
||||
_pluginsManager.notify(&scnN);
|
||||
|
||||
return false;
|
||||
}
|
||||
bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode();
|
||||
doClose(bufferID, MAIN_VIEW, isSnapshotMode);
|
||||
doClose(bufferID, SUB_VIEW, isSnapshotMode);
|
||||
|
||||
scnN.nmhdr.code = NPPN_FILEDELETED;
|
||||
scnN.nmhdr.idFrom = (uptr_t)-1;
|
||||
_pluginsManager.notify(&scnN);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -2903,286 +2903,286 @@ void FindIncrementDlg::addToRebar(ReBar * rebar)
|
||||
_pRebar->setGrayBackground(_rbBand.wID);
|
||||
}
|
||||
|
||||
const TCHAR CProgress::cClassName[] = TEXT("NppProgressClass");
|
||||
const TCHAR CProgress::cDefaultHeader[] = TEXT("Operation progress...");
|
||||
const int CProgress::cBackgroundColor = COLOR_3DFACE;
|
||||
const int CProgress::cPBwidth = 600;
|
||||
const int CProgress::cPBheight = 10;
|
||||
const int CProgress::cBTNwidth = 80;
|
||||
const int CProgress::cBTNheight = 25;
|
||||
|
||||
|
||||
volatile LONG CProgress::RefCount = 0;
|
||||
HINSTANCE CProgress::HInst = NULL;
|
||||
|
||||
|
||||
CProgress::CProgress() : _hwnd(NULL)
|
||||
{
|
||||
if (::InterlockedIncrement(&RefCount) == 1)
|
||||
{
|
||||
::GetModuleHandleEx(
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_PIN, cClassName, &HInst);
|
||||
|
||||
WNDCLASSEX wcex;
|
||||
|
||||
::SecureZeroMemory(&wcex, sizeof(wcex));
|
||||
wcex.cbSize = sizeof(wcex);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = wndProc;
|
||||
wcex.hInstance = HInst;
|
||||
wcex.hCursor = ::LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = ::GetSysColorBrush(cBackgroundColor);
|
||||
wcex.lpszClassName = cClassName;
|
||||
|
||||
::RegisterClassEx(&wcex);
|
||||
|
||||
INITCOMMONCONTROLSEX icex;
|
||||
|
||||
::SecureZeroMemory(&icex, sizeof(icex));
|
||||
icex.dwSize = sizeof(icex);
|
||||
icex.dwICC = ICC_STANDARD_CLASSES | ICC_PROGRESS_CLASS;
|
||||
|
||||
::InitCommonControlsEx(&icex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CProgress::~CProgress()
|
||||
{
|
||||
Close();
|
||||
|
||||
if (::InterlockedDecrement(&RefCount) == 0)
|
||||
::UnregisterClass(cClassName, HInst);
|
||||
}
|
||||
|
||||
|
||||
HWND CProgress::Open(HWND hOwner, const TCHAR* header)
|
||||
{
|
||||
if (_hwnd)
|
||||
return _hwnd;
|
||||
|
||||
_hOwner = hOwner;
|
||||
|
||||
if (header)
|
||||
_tcscpy_s(_header, _countof(_header), header);
|
||||
else
|
||||
_tcscpy_s(_header, _countof(_header), cDefaultHeader);
|
||||
|
||||
// Create manually reset non-signaled event
|
||||
_hActiveState = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!_hActiveState)
|
||||
return NULL;
|
||||
|
||||
_hThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadFunc,
|
||||
(LPVOID)this, 0, NULL);
|
||||
if (!_hThread)
|
||||
{
|
||||
::CloseHandle(_hActiveState);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Wait for the progress window to be created
|
||||
::WaitForSingleObject(_hActiveState, INFINITE);
|
||||
|
||||
// On progress window create fail
|
||||
if (!_hwnd)
|
||||
{
|
||||
::WaitForSingleObject(_hThread, INFINITE);
|
||||
::CloseHandle(_hThread);
|
||||
::CloseHandle(_hActiveState);
|
||||
}
|
||||
|
||||
return _hwnd;
|
||||
}
|
||||
|
||||
|
||||
bool CProgress::IsCancelled() const
|
||||
{
|
||||
if (_hwnd)
|
||||
return (::WaitForSingleObject(_hActiveState, 0) != WAIT_OBJECT_0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CProgress::SetPercent(unsigned percent, const TCHAR *fileName) const
|
||||
{
|
||||
if (_hwnd)
|
||||
{
|
||||
::SendNotifyMessage(_hPBar, PBM_SETPOS, (WPARAM)percent, 0);
|
||||
::SendMessage(_hPText, WM_SETTEXT, 0, (LPARAM)fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CProgress::Close()
|
||||
{
|
||||
if (_hwnd)
|
||||
{
|
||||
::SendMessage(_hwnd, WM_CLOSE, 0, 0);
|
||||
_hwnd = NULL;
|
||||
::WaitForSingleObject(_hThread, INFINITE);
|
||||
::CloseHandle(_hThread);
|
||||
::CloseHandle(_hActiveState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DWORD CProgress::threadFunc(LPVOID data)
|
||||
{
|
||||
CProgress* pw = static_cast<CProgress*>(data);
|
||||
return (DWORD)pw->thread();
|
||||
}
|
||||
|
||||
|
||||
int CProgress::thread()
|
||||
{
|
||||
BOOL r = createProgressWindow();
|
||||
::SetEvent(_hActiveState);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
// Window message loop
|
||||
MSG msg;
|
||||
while ((r = ::GetMessage(&msg, NULL, 0, 0)) != 0 && r != -1)
|
||||
{
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int CProgress::createProgressWindow()
|
||||
{
|
||||
DWORD styleEx = WS_EX_OVERLAPPEDWINDOW;
|
||||
if (_hOwner)
|
||||
styleEx |= WS_EX_TOOLWINDOW;
|
||||
|
||||
_hwnd = ::CreateWindowEx(styleEx,
|
||||
cClassName, _header, WS_POPUP | WS_CAPTION,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
_hOwner, NULL, HInst, (LPVOID)this);
|
||||
if (!_hwnd)
|
||||
return -1;
|
||||
|
||||
int width = cPBwidth + 10;
|
||||
int height = cPBheight + cBTNheight + 35;
|
||||
RECT win = adjustSizeAndPos(width, height);
|
||||
::MoveWindow(_hwnd, win.left, win.top,
|
||||
win.right - win.left, win.bottom - win.top, TRUE);
|
||||
|
||||
::GetClientRect(_hwnd, &win);
|
||||
width = win.right - win.left;
|
||||
height = win.bottom - win.top;
|
||||
|
||||
_hPText = ::CreateWindowEx(0, TEXT("STATIC"), TEXT(""),
|
||||
WS_CHILD | WS_VISIBLE | BS_TEXT,
|
||||
5, 5,
|
||||
width - 10, 20, _hwnd, NULL, HInst, NULL);
|
||||
HFONT hf = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
|
||||
const TCHAR CProgress::cClassName[] = TEXT("NppProgressClass");
|
||||
const TCHAR CProgress::cDefaultHeader[] = TEXT("Operation progress...");
|
||||
const int CProgress::cBackgroundColor = COLOR_3DFACE;
|
||||
const int CProgress::cPBwidth = 600;
|
||||
const int CProgress::cPBheight = 10;
|
||||
const int CProgress::cBTNwidth = 80;
|
||||
const int CProgress::cBTNheight = 25;
|
||||
|
||||
|
||||
volatile LONG CProgress::RefCount = 0;
|
||||
HINSTANCE CProgress::HInst = NULL;
|
||||
|
||||
|
||||
CProgress::CProgress() : _hwnd(NULL)
|
||||
{
|
||||
if (::InterlockedIncrement(&RefCount) == 1)
|
||||
{
|
||||
::GetModuleHandleEx(
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_PIN, cClassName, &HInst);
|
||||
|
||||
WNDCLASSEX wcex;
|
||||
|
||||
::SecureZeroMemory(&wcex, sizeof(wcex));
|
||||
wcex.cbSize = sizeof(wcex);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = wndProc;
|
||||
wcex.hInstance = HInst;
|
||||
wcex.hCursor = ::LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = ::GetSysColorBrush(cBackgroundColor);
|
||||
wcex.lpszClassName = cClassName;
|
||||
|
||||
::RegisterClassEx(&wcex);
|
||||
|
||||
INITCOMMONCONTROLSEX icex;
|
||||
|
||||
::SecureZeroMemory(&icex, sizeof(icex));
|
||||
icex.dwSize = sizeof(icex);
|
||||
icex.dwICC = ICC_STANDARD_CLASSES | ICC_PROGRESS_CLASS;
|
||||
|
||||
::InitCommonControlsEx(&icex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CProgress::~CProgress()
|
||||
{
|
||||
Close();
|
||||
|
||||
if (::InterlockedDecrement(&RefCount) == 0)
|
||||
::UnregisterClass(cClassName, HInst);
|
||||
}
|
||||
|
||||
|
||||
HWND CProgress::Open(HWND hOwner, const TCHAR* header)
|
||||
{
|
||||
if (_hwnd)
|
||||
return _hwnd;
|
||||
|
||||
_hOwner = hOwner;
|
||||
|
||||
if (header)
|
||||
_tcscpy_s(_header, _countof(_header), header);
|
||||
else
|
||||
_tcscpy_s(_header, _countof(_header), cDefaultHeader);
|
||||
|
||||
// Create manually reset non-signaled event
|
||||
_hActiveState = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!_hActiveState)
|
||||
return NULL;
|
||||
|
||||
_hThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadFunc,
|
||||
(LPVOID)this, 0, NULL);
|
||||
if (!_hThread)
|
||||
{
|
||||
::CloseHandle(_hActiveState);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Wait for the progress window to be created
|
||||
::WaitForSingleObject(_hActiveState, INFINITE);
|
||||
|
||||
// On progress window create fail
|
||||
if (!_hwnd)
|
||||
{
|
||||
::WaitForSingleObject(_hThread, INFINITE);
|
||||
::CloseHandle(_hThread);
|
||||
::CloseHandle(_hActiveState);
|
||||
}
|
||||
|
||||
return _hwnd;
|
||||
}
|
||||
|
||||
|
||||
bool CProgress::IsCancelled() const
|
||||
{
|
||||
if (_hwnd)
|
||||
return (::WaitForSingleObject(_hActiveState, 0) != WAIT_OBJECT_0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CProgress::SetPercent(unsigned percent, const TCHAR *fileName) const
|
||||
{
|
||||
if (_hwnd)
|
||||
{
|
||||
::SendNotifyMessage(_hPBar, PBM_SETPOS, (WPARAM)percent, 0);
|
||||
::SendMessage(_hPText, WM_SETTEXT, 0, (LPARAM)fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CProgress::Close()
|
||||
{
|
||||
if (_hwnd)
|
||||
{
|
||||
::SendMessage(_hwnd, WM_CLOSE, 0, 0);
|
||||
_hwnd = NULL;
|
||||
::WaitForSingleObject(_hThread, INFINITE);
|
||||
::CloseHandle(_hThread);
|
||||
::CloseHandle(_hActiveState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DWORD CProgress::threadFunc(LPVOID data)
|
||||
{
|
||||
CProgress* pw = static_cast<CProgress*>(data);
|
||||
return (DWORD)pw->thread();
|
||||
}
|
||||
|
||||
|
||||
int CProgress::thread()
|
||||
{
|
||||
BOOL r = createProgressWindow();
|
||||
::SetEvent(_hActiveState);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
// Window message loop
|
||||
MSG msg;
|
||||
while ((r = ::GetMessage(&msg, NULL, 0, 0)) != 0 && r != -1)
|
||||
{
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int CProgress::createProgressWindow()
|
||||
{
|
||||
DWORD styleEx = WS_EX_OVERLAPPEDWINDOW;
|
||||
if (_hOwner)
|
||||
styleEx |= WS_EX_TOOLWINDOW;
|
||||
|
||||
_hwnd = ::CreateWindowEx(styleEx,
|
||||
cClassName, _header, WS_POPUP | WS_CAPTION,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
_hOwner, NULL, HInst, (LPVOID)this);
|
||||
if (!_hwnd)
|
||||
return -1;
|
||||
|
||||
int width = cPBwidth + 10;
|
||||
int height = cPBheight + cBTNheight + 35;
|
||||
RECT win = adjustSizeAndPos(width, height);
|
||||
::MoveWindow(_hwnd, win.left, win.top,
|
||||
win.right - win.left, win.bottom - win.top, TRUE);
|
||||
|
||||
::GetClientRect(_hwnd, &win);
|
||||
width = win.right - win.left;
|
||||
height = win.bottom - win.top;
|
||||
|
||||
_hPText = ::CreateWindowEx(0, TEXT("STATIC"), TEXT(""),
|
||||
WS_CHILD | WS_VISIBLE | BS_TEXT,
|
||||
5, 5,
|
||||
width - 10, 20, _hwnd, NULL, HInst, NULL);
|
||||
HFONT hf = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
|
||||
if (hf)
|
||||
::SendMessage(_hPText, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE, 0));
|
||||
|
||||
_hPBar = ::CreateWindowEx(0, PROGRESS_CLASS, TEXT("Progress Bar"),
|
||||
WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
|
||||
5, 25, width - 10, cPBheight,
|
||||
_hwnd, NULL, HInst, NULL);
|
||||
SendMessage(_hPBar, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
|
||||
|
||||
_hBtn = ::CreateWindowEx(0, TEXT("BUTTON"), TEXT("Cancel"),
|
||||
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_TEXT,
|
||||
(width - cBTNwidth) / 2, height - cBTNheight - 5,
|
||||
cBTNwidth, cBTNheight, _hwnd, NULL, HInst, NULL);
|
||||
|
||||
::SendMessage(_hPText, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE, 0));
|
||||
|
||||
_hPBar = ::CreateWindowEx(0, PROGRESS_CLASS, TEXT("Progress Bar"),
|
||||
WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
|
||||
5, 25, width - 10, cPBheight,
|
||||
_hwnd, NULL, HInst, NULL);
|
||||
SendMessage(_hPBar, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
|
||||
|
||||
_hBtn = ::CreateWindowEx(0, TEXT("BUTTON"), TEXT("Cancel"),
|
||||
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_TEXT,
|
||||
(width - cBTNwidth) / 2, height - cBTNheight - 5,
|
||||
cBTNwidth, cBTNheight, _hwnd, NULL, HInst, NULL);
|
||||
|
||||
|
||||
if (hf)
|
||||
::SendMessage(_hBtn, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE, 0));
|
||||
|
||||
::ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||
::UpdateWindow(_hwnd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
RECT CProgress::adjustSizeAndPos(int width, int height)
|
||||
{
|
||||
RECT win, maxWin;
|
||||
|
||||
::GetWindowRect(::GetDesktopWindow(), &maxWin);
|
||||
win = maxWin;
|
||||
win.right = win.left + width;
|
||||
win.bottom = win.top + height;
|
||||
|
||||
::AdjustWindowRectEx(&win, ::GetWindowLongPtr(_hwnd, GWL_STYLE),
|
||||
FALSE, ::GetWindowLongPtr(_hwnd, GWL_EXSTYLE));
|
||||
|
||||
width = win.right - win.left;
|
||||
height = win.bottom - win.top;
|
||||
|
||||
if (width < maxWin.right - maxWin.left)
|
||||
{
|
||||
win.left = (maxWin.left + maxWin.right - width) / 2;
|
||||
win.right = win.left + width;
|
||||
}
|
||||
else
|
||||
{
|
||||
win.left = maxWin.left;
|
||||
win.right = maxWin.right;
|
||||
}
|
||||
|
||||
if (height < maxWin.right - maxWin.left)
|
||||
{
|
||||
win.top = (maxWin.top + maxWin.bottom - height) / 2;
|
||||
win.bottom = win.top + height;
|
||||
}
|
||||
else
|
||||
{
|
||||
win.top = maxWin.top;
|
||||
win.bottom = maxWin.bottom;
|
||||
}
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
|
||||
LRESULT APIENTRY CProgress::wndProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (umsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
CProgress* pw =(CProgress*)((LPCREATESTRUCT)lparam)->lpCreateParams;
|
||||
::SetWindowLongPtr(hwnd, GWLP_USERDATA, PtrToUlong(pw));
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_SETFOCUS:
|
||||
{
|
||||
CProgress* pw = reinterpret_cast<CProgress*>(static_cast<LONG_PTR>
|
||||
(::GetWindowLongPtr(hwnd, GWLP_USERDATA)));
|
||||
::SetFocus(pw->_hBtn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
if (HIWORD(wparam) == BN_CLICKED)
|
||||
{
|
||||
CProgress* pw =
|
||||
reinterpret_cast<CProgress*>(static_cast<LONG_PTR>
|
||||
(::GetWindowLongPtr(hwnd, GWLP_USERDATA)));
|
||||
::ResetEvent(pw->_hActiveState);
|
||||
::EnableWindow(pw->_hBtn, FALSE);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
::PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ::DefWindowProc(hwnd, umsg, wparam, lparam);
|
||||
}
|
||||
::SendMessage(_hBtn, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE, 0));
|
||||
|
||||
::ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||
::UpdateWindow(_hwnd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
RECT CProgress::adjustSizeAndPos(int width, int height)
|
||||
{
|
||||
RECT win, maxWin;
|
||||
|
||||
::GetWindowRect(::GetDesktopWindow(), &maxWin);
|
||||
win = maxWin;
|
||||
win.right = win.left + width;
|
||||
win.bottom = win.top + height;
|
||||
|
||||
::AdjustWindowRectEx(&win, ::GetWindowLongPtr(_hwnd, GWL_STYLE),
|
||||
FALSE, ::GetWindowLongPtr(_hwnd, GWL_EXSTYLE));
|
||||
|
||||
width = win.right - win.left;
|
||||
height = win.bottom - win.top;
|
||||
|
||||
if (width < maxWin.right - maxWin.left)
|
||||
{
|
||||
win.left = (maxWin.left + maxWin.right - width) / 2;
|
||||
win.right = win.left + width;
|
||||
}
|
||||
else
|
||||
{
|
||||
win.left = maxWin.left;
|
||||
win.right = maxWin.right;
|
||||
}
|
||||
|
||||
if (height < maxWin.right - maxWin.left)
|
||||
{
|
||||
win.top = (maxWin.top + maxWin.bottom - height) / 2;
|
||||
win.bottom = win.top + height;
|
||||
}
|
||||
else
|
||||
{
|
||||
win.top = maxWin.top;
|
||||
win.bottom = maxWin.bottom;
|
||||
}
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
|
||||
LRESULT APIENTRY CProgress::wndProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (umsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
CProgress* pw =(CProgress*)((LPCREATESTRUCT)lparam)->lpCreateParams;
|
||||
::SetWindowLongPtr(hwnd, GWLP_USERDATA, PtrToUlong(pw));
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_SETFOCUS:
|
||||
{
|
||||
CProgress* pw = reinterpret_cast<CProgress*>(static_cast<LONG_PTR>
|
||||
(::GetWindowLongPtr(hwnd, GWLP_USERDATA)));
|
||||
::SetFocus(pw->_hBtn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
if (HIWORD(wparam) == BN_CLICKED)
|
||||
{
|
||||
CProgress* pw =
|
||||
reinterpret_cast<CProgress*>(static_cast<LONG_PTR>
|
||||
(::GetWindowLongPtr(hwnd, GWLP_USERDATA)));
|
||||
::ResetEvent(pw->_hActiveState);
|
||||
::EnableWindow(pw->_hBtn, FALSE);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
::PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ::DefWindowProc(hwnd, umsg, wparam, lparam);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user