[MSPAINT] Use wait cursor (#5660)

- Implement CWaitCursor class in newly-added "waitcursor.h".
- Use CWaitCursor to manage the wait cursor.
- Improve WM_SETCURSOR handlings.
CORE-19094
This commit is contained in:
Katayama Hirofumi MZ 2023-09-10 22:28:28 +09:00 committed by GitHub
parent 0ef9cfb04e
commit 993a45024e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 119 additions and 31 deletions

View file

@ -635,6 +635,12 @@ LRESULT CCanvasWindow::OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL
LRESULT CCanvasWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (CWaitCursor::IsWaiting())
{
bHandled = FALSE;
return 0;
}
POINT pt;
::GetCursorPos(&pt);
ScreenToClient(&pt);

View file

@ -151,6 +151,8 @@ GetDIBHeight(HBITMAP hBitmap)
BOOL SaveDIBToFile(HBITMAP hBitmap, LPCWSTR FileName, BOOL fIsMainFile, REFGUID guidFileType)
{
CWaitCursor waitCursor;
CImageDx img;
img.Attach(hBitmap);
HRESULT hr = img.SaveDx(FileName, guidFileType, g_xDpi, g_yDpi);
@ -250,6 +252,8 @@ HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCWSTR name, LPWIN32_FIND_DATAW pFoun
HBITMAP DoLoadImageFile(HWND hwnd, LPCWSTR name, BOOL fIsMainFile)
{
CWaitCursor waitCursor;
// find the file
WIN32_FIND_DATA find;
HANDLE hFind = ::FindFirstFileW(name, &find);
@ -341,6 +345,8 @@ HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono)
HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical, BOOL bMono)
{
CWaitCursor waitCursor;
if (nDegree == 0)
return CopyDIBImage(hbm);
@ -402,6 +408,8 @@ struct BITMAPINFODX : BITMAPINFO
HGLOBAL BitmapToClipboardDIB(HBITMAP hBitmap)
{
CWaitCursor waitCursor;
BITMAP bm;
if (!GetObject(hBitmap, sizeof(BITMAP), &bm))
return NULL;
@ -463,6 +471,8 @@ HGLOBAL BitmapToClipboardDIB(HBITMAP hBitmap)
HBITMAP BitmapFromClipboardDIB(HGLOBAL hGlobal)
{
CWaitCursor waitCursor;
LPBYTE pb = (LPBYTE)GlobalLock(hGlobal);
if (!pb)
return NULL;
@ -508,6 +518,8 @@ HBITMAP BitmapFromClipboardDIB(HGLOBAL hGlobal)
HBITMAP BitmapFromHEMF(HENHMETAFILE hEMF)
{
CWaitCursor waitCursor;
ENHMETAHEADER header;
if (!GetEnhMetaFileHeader(hEMF, sizeof(header), &header))
return NULL;
@ -529,6 +541,8 @@ HBITMAP BitmapFromHEMF(HENHMETAFILE hEMF)
BOOL IsBitmapBlackAndWhite(HBITMAP hbm)
{
CWaitCursor waitCursor;
BITMAP bm;
if (!::GetObjectW(hbm, sizeof(bm), &bm))
return FALSE;
@ -578,6 +592,8 @@ Finish:
HBITMAP ConvertToBlackAndWhite(HBITMAP hbm)
{
CWaitCursor waitCursor;
BITMAP bm;
if (!::GetObject(hbm, sizeof(bm), &bm))
return NULL;

View file

@ -50,6 +50,7 @@
#include "toolsmodel.h"
#include "winproc.h"
#include "dialogs.h"
#include "waitcursor.h"
#include "globalvar.h"
#endif /* _MSPAINT_H */

View file

@ -187,6 +187,12 @@ LRESULT CTextEditWindow::OnNCHitTest(UINT nMsg, WPARAM wParam, LPARAM lParam, BO
LRESULT CTextEditWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (CWaitCursor::IsWaiting())
{
bHandled = FALSE;
return 0;
}
UINT nHitTest = LOWORD(lParam);
if (nHitTest == HTCAPTION)
{

View file

@ -0,0 +1,54 @@
/*
* PROJECT: PAINT for ReactOS
* LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
* PURPOSE: Wait cursor management
* COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*/
#pragma once
class CWaitCursor
{
public:
CWaitCursor()
{
if (s_nLock++ == 0)
{
if (!s_hWaitCursor)
s_hWaitCursor = ::LoadCursor(NULL, IDC_WAIT);
s_hOldCursor = ::SetCursor(s_hWaitCursor);
}
else
{
::SetCursor(s_hWaitCursor);
}
}
~CWaitCursor()
{
if (--s_nLock == 0)
{
::SetCursor(s_hOldCursor);
s_hOldCursor = NULL;
}
}
CWaitCursor(const CWaitCursor&) = delete;
CWaitCursor& operator=(const CWaitCursor&) = delete;
static BOOL IsWaiting()
{
return s_nLock > 0;
}
static void KeepWait()
{
::SetCursor(s_hWaitCursor);
}
protected:
static LONG s_nLock;
static HCURSOR s_hOldCursor;
static HCURSOR s_hWaitCursor;
};
DECLSPEC_SELECTANY LONG CWaitCursor::s_nLock = 0;
DECLSPEC_SELECTANY HCURSOR CWaitCursor::s_hOldCursor = NULL;
DECLSPEC_SELECTANY HCURSOR CWaitCursor::s_hWaitCursor = NULL;

View file

@ -911,44 +911,48 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
imageModel.NotifyImageChanged();
break;
case IDM_IMAGEROTATEMIRROR:
switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd))
{
case 1: /* flip horizontally */
if (selectionModel.m_bShow)
selectionModel.FlipHorizontally();
else
imageModel.FlipHorizontally();
break;
case 2: /* flip vertically */
if (selectionModel.m_bShow)
selectionModel.FlipVertically();
else
imageModel.FlipVertically();
break;
case 3: /* rotate 90 degrees */
if (selectionModel.m_bShow)
selectionModel.RotateNTimes90Degrees(1);
else
imageModel.RotateNTimes90Degrees(1);
break;
case 4: /* rotate 180 degrees */
if (selectionModel.m_bShow)
selectionModel.RotateNTimes90Degrees(2);
else
imageModel.RotateNTimes90Degrees(2);
break;
case 5: /* rotate 270 degrees */
if (selectionModel.m_bShow)
selectionModel.RotateNTimes90Degrees(3);
else
imageModel.RotateNTimes90Degrees(3);
break;
CWaitCursor waitCursor;
switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd))
{
case 1: /* flip horizontally */
if (selectionModel.m_bShow)
selectionModel.FlipHorizontally();
else
imageModel.FlipHorizontally();
break;
case 2: /* flip vertically */
if (selectionModel.m_bShow)
selectionModel.FlipVertically();
else
imageModel.FlipVertically();
break;
case 3: /* rotate 90 degrees */
if (selectionModel.m_bShow)
selectionModel.RotateNTimes90Degrees(1);
else
imageModel.RotateNTimes90Degrees(1);
break;
case 4: /* rotate 180 degrees */
if (selectionModel.m_bShow)
selectionModel.RotateNTimes90Degrees(2);
else
imageModel.RotateNTimes90Degrees(2);
break;
case 5: /* rotate 270 degrees */
if (selectionModel.m_bShow)
selectionModel.RotateNTimes90Degrees(3);
else
imageModel.RotateNTimes90Degrees(3);
break;
}
}
break;
case IDM_IMAGEATTRIBUTES:
{
if (attributesDialog.DoModal(mainWindow.m_hWnd))
{
CWaitCursor waitCursor;
if (attributesDialog.m_bBlackAndWhite && !imageModel.IsBlackAndWhite())
{
CString strText(MAKEINTRESOURCE(IDS_LOSECOLOR));
@ -972,6 +976,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
{
if (stretchSkewDialog.DoModal(mainWindow.m_hWnd))
{
CWaitCursor waitCursor;
if (selectionModel.m_bShow)
{
selectionModel.StretchSkew(stretchSkewDialog.percentage.x, stretchSkewDialog.percentage.y,