[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) LRESULT CCanvasWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ {
if (CWaitCursor::IsWaiting())
{
bHandled = FALSE;
return 0;
}
POINT pt; POINT pt;
::GetCursorPos(&pt); ::GetCursorPos(&pt);
ScreenToClient(&pt); ScreenToClient(&pt);

View file

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

View file

@ -50,6 +50,7 @@
#include "toolsmodel.h" #include "toolsmodel.h"
#include "winproc.h" #include "winproc.h"
#include "dialogs.h" #include "dialogs.h"
#include "waitcursor.h"
#include "globalvar.h" #include "globalvar.h"
#endif /* _MSPAINT_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) LRESULT CTextEditWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ {
if (CWaitCursor::IsWaiting())
{
bHandled = FALSE;
return 0;
}
UINT nHitTest = LOWORD(lParam); UINT nHitTest = LOWORD(lParam);
if (nHitTest == HTCAPTION) 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(); imageModel.NotifyImageChanged();
break; break;
case IDM_IMAGEROTATEMIRROR: case IDM_IMAGEROTATEMIRROR:
switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd))
{ {
case 1: /* flip horizontally */ CWaitCursor waitCursor;
if (selectionModel.m_bShow) switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd))
selectionModel.FlipHorizontally(); {
else case 1: /* flip horizontally */
imageModel.FlipHorizontally(); if (selectionModel.m_bShow)
break; selectionModel.FlipHorizontally();
case 2: /* flip vertically */ else
if (selectionModel.m_bShow) imageModel.FlipHorizontally();
selectionModel.FlipVertically(); break;
else case 2: /* flip vertically */
imageModel.FlipVertically(); if (selectionModel.m_bShow)
break; selectionModel.FlipVertically();
case 3: /* rotate 90 degrees */ else
if (selectionModel.m_bShow) imageModel.FlipVertically();
selectionModel.RotateNTimes90Degrees(1); break;
else case 3: /* rotate 90 degrees */
imageModel.RotateNTimes90Degrees(1); if (selectionModel.m_bShow)
break; selectionModel.RotateNTimes90Degrees(1);
case 4: /* rotate 180 degrees */ else
if (selectionModel.m_bShow) imageModel.RotateNTimes90Degrees(1);
selectionModel.RotateNTimes90Degrees(2); break;
else case 4: /* rotate 180 degrees */
imageModel.RotateNTimes90Degrees(2); if (selectionModel.m_bShow)
break; selectionModel.RotateNTimes90Degrees(2);
case 5: /* rotate 270 degrees */ else
if (selectionModel.m_bShow) imageModel.RotateNTimes90Degrees(2);
selectionModel.RotateNTimes90Degrees(3); break;
else case 5: /* rotate 270 degrees */
imageModel.RotateNTimes90Degrees(3); if (selectionModel.m_bShow)
break; selectionModel.RotateNTimes90Degrees(3);
else
imageModel.RotateNTimes90Degrees(3);
break;
}
} }
break; break;
case IDM_IMAGEATTRIBUTES: case IDM_IMAGEATTRIBUTES:
{ {
if (attributesDialog.DoModal(mainWindow.m_hWnd)) if (attributesDialog.DoModal(mainWindow.m_hWnd))
{ {
CWaitCursor waitCursor;
if (attributesDialog.m_bBlackAndWhite && !imageModel.IsBlackAndWhite()) if (attributesDialog.m_bBlackAndWhite && !imageModel.IsBlackAndWhite())
{ {
CString strText(MAKEINTRESOURCE(IDS_LOSECOLOR)); 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)) if (stretchSkewDialog.DoModal(mainWindow.m_hWnd))
{ {
CWaitCursor waitCursor;
if (selectionModel.m_bShow) if (selectionModel.m_bShow)
{ {
selectionModel.StretchSkew(stretchSkewDialog.percentage.x, stretchSkewDialog.percentage.y, selectionModel.StretchSkew(stretchSkewDialog.percentage.x, stretchSkewDialog.percentage.y,