ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
November 2023
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
20 participants
274 discussions
Start a n
N
ew thread
[reactos] 01/01: [NETCFGX] Fix TCP/IP alternate radiobutton behaviour (#6039)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d74d4e0395f0940563c76…
commit d74d4e0395f0940563c76d253947505265428d9c Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Sat Nov 25 22:47:46 2023 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Sat Nov 25 22:47:46 2023 +0900 [NETCFGX] Fix TCP/IP alternate radiobutton behaviour (#6039) Based on KRosUser's netaltconf_fix.patch. CORE-19336 --- dll/win32/netcfgx/tcpipconf_notify.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dll/win32/netcfgx/tcpipconf_notify.c b/dll/win32/netcfgx/tcpipconf_notify.c index cc64370e856..e6db3ae9a1d 100644 --- a/dll/win32/netcfgx/tcpipconf_notify.c +++ b/dll/win32/netcfgx/tcpipconf_notify.c @@ -2223,7 +2223,7 @@ TcpipAltConfDlg( { TcpipConfNotifyImpl *This; LPPROPSHEETPAGE page; - BOOL bEnabled; + BOOL bNoDHCP; switch (uMsg) { @@ -2245,19 +2245,19 @@ TcpipAltConfDlg( { if (HIWORD(wParam) == BN_CLICKED) { - bEnabled = (IsDlgButtonChecked(hwndDlg, IDC_USEDHCP) == BST_CHECKED); - if (bEnabled) + bNoDHCP = (IsDlgButtonChecked(hwndDlg, IDC_NODHCP) == BST_CHECKED); + if (bNoDHCP) { SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_CLEARADDRESS, 0, 0); SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_CLEARADDRESS, 0, 0); SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_CLEARADDRESS, 0, 0); } - EnableWindow(GetDlgItem(hwndDlg, IDC_IPADDR), bEnabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_SUBNETMASK), bEnabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_DEFGATEWAY), bEnabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), bEnabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), bEnabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_IPADDR), bNoDHCP); + EnableWindow(GetDlgItem(hwndDlg, IDC_SUBNETMASK), bNoDHCP); + EnableWindow(GetDlgItem(hwndDlg, IDC_DEFGATEWAY), bNoDHCP); + EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), bNoDHCP); + EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), bNoDHCP); PropSheet_Changed(GetParent(hwndDlg), hwndDlg); }
1 year, 1 month
1
0
0
0
[reactos] 01/01: [IMM32][SDK][NTUSER][IMM32_WINETEST] Add CtfImmGenerateMessage (#6037)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3b2fdc56bdd8c13b433de…
commit 3b2fdc56bdd8c13b433de96b2ca212fe82524c54 Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Sat Nov 25 22:46:00 2023 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Sat Nov 25 22:46:00 2023 +0900 [IMM32][SDK][NTUSER][IMM32_WINETEST] Add CtfImmGenerateMessage (#6037) Implementing advanced text service... - Add CtfImmGenerateMessage function. - Modify imm32.spec. - Move TRANSMSG, TRANSMSGLIST etc. in win32ss/include/ntuser.h to <immdev.h>. - Move win32ss/include/imetable.h to sdk/include/reactos/imetable.h. - Move dll/win32/imm32/CtfImeTable.h to sdk/include/reactos/CtfImeTable.h. - Fix build failure of imm32_winetest due to TRANSMSG redefinition. CORE-19268 --- dll/win32/imm32/ctf.c | 98 +++++++++++++++++++- dll/win32/imm32/ime.c | 6 +- dll/win32/imm32/imm32.spec | 1 + modules/rostests/winetests/imm32/imm32.c | 2 + sdk/include/ddk/immdev.h | 101 +++++++++++++++++++++ .../imm32 => sdk/include/reactos}/CtfImeTable.h | 0 .../include => sdk/include/reactos}/imetable.h | 0 sdk/include/reactos/imm32_undoc.h | 1 + win32ss/include/ntuser.h | 101 --------------------- 9 files changed, 201 insertions(+), 109 deletions(-) diff --git a/dll/win32/imm32/ctf.c b/dll/win32/imm32/ctf.c index 78f9b09acb9..1fc124f24b5 100644 --- a/dll/win32/imm32/ctf.c +++ b/dll/win32/imm32/ctf.c @@ -134,7 +134,7 @@ VOID Imm32TF_InvalidAssemblyListCacheIfExist(VOID) * new-style and high-level input method. * * The CTF IME file is a DLL file that the software developer distributes. - * The export functions of the CTF IME file are defined in "CtfImeTable.h" of + * The export functions of the CTF IME file are defined in <CtfImeTable.h> of * this folder. */ @@ -148,13 +148,13 @@ HINSTANCE g_hCtfIme = NULL; #undef DEFINE_CTF_IME_FN #define DEFINE_CTF_IME_FN(func_name, ret_type, params) \ typedef ret_type (WINAPI *FN_##func_name)params; -#include "CtfImeTable.h" +#include <CtfImeTable.h> /* Define the global variables (g_pfn...) for CTF IME functions */ #undef DEFINE_CTF_IME_FN #define DEFINE_CTF_IME_FN(func_name, ret_type, params) \ FN_##func_name g_pfn##func_name = NULL; -#include "CtfImeTable.h" +#include <CtfImeTable.h> /* The macro that gets the variable name from the CTF IME function name */ #define CTF_IME_FN(func_name) g_pfn##func_name @@ -256,7 +256,7 @@ Imm32LoadCtfIme(VOID) bSuccess = FALSE; /* Failed */ \ break; \ } -#include "CtfImeTable.h" +#include <CtfImeTable.h> } while (0); /* Unload the CTF IME if failed */ @@ -265,7 +265,7 @@ Imm32LoadCtfIme(VOID) /* Set NULL to the function pointers */ #undef DEFINE_CTF_IME_FN #define DEFINE_CTF_IME_FN(func_name, ret_type, params) CTF_IME_FN(func_name) = NULL; -#include "CtfImeTable.h" +#include <CtfImeTable.h> if (g_hCtfIme) { @@ -493,6 +493,94 @@ CtfImmTIMActivate(_In_ HKL hKL) return E_NOTIMPL; } +/*********************************************************************** + * CtfImmGenerateMessage(IMM32.@) + */ +BOOL WINAPI +CtfImmGenerateMessage( + _In_ HIMC hIMC, + _In_ BOOL bSend) +{ + DWORD_PTR dwImeThreadId, dwCurrentThreadId; + PCLIENTIMC pClientImc; + BOOL bUnicode; + LPINPUTCONTEXT pIC; + DWORD iMsg, dwNumMsgBuf; + LPTRANSMSG pOldTransMsg, pNewTransMsg; + SIZE_T cbTransMsg; + + TRACE("(%p, %d)\n", hIMC, bSend); + + dwImeThreadId = NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID); + dwCurrentThreadId = GetCurrentThreadId(); + if (dwImeThreadId != dwCurrentThreadId) + { + ERR("%p vs %p\n", dwImeThreadId, dwCurrentThreadId); + return FALSE; + } + + pClientImc = ImmLockClientImc(hIMC); + if (IS_NULL_UNEXPECTEDLY(pClientImc)) + return FALSE; + + bUnicode = !!(pClientImc->dwFlags & CLIENTIMC_WIDE); + ImmUnlockClientImc(pClientImc); + + pIC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); + if (IS_NULL_UNEXPECTEDLY(pIC)) + return FALSE; + + dwNumMsgBuf = pIC->dwNumMsgBuf; + pOldTransMsg = (LPTRANSMSG)ImmLockIMCC(pIC->hMsgBuf); + if (IS_NULL_UNEXPECTEDLY(pOldTransMsg)) + { + pIC->dwNumMsgBuf = 0; + ImmUnlockIMC(hIMC); + return TRUE; + } + + cbTransMsg = sizeof(TRANSMSG) * dwNumMsgBuf; + pNewTransMsg = (PTRANSMSG)ImmLocalAlloc(0, cbTransMsg); + if (IS_NULL_UNEXPECTEDLY(pNewTransMsg)) + { + ImmUnlockIMCC(pIC->hMsgBuf); + pIC->dwNumMsgBuf = 0; + ImmUnlockIMC(hIMC); + return TRUE; + } + + RtlCopyMemory(pNewTransMsg, pOldTransMsg, cbTransMsg); + + for (iMsg = 0; iMsg < dwNumMsgBuf; ++iMsg) + { + HWND hWnd = pIC->hWnd; + UINT uMsg = pNewTransMsg[iMsg].message; + WPARAM wParam = pNewTransMsg[iMsg].wParam; + LPARAM lParam = pNewTransMsg[iMsg].lParam; + if (bSend) + { + if (bUnicode) + SendMessageW(hWnd, uMsg, wParam, lParam); + else + SendMessageA(hWnd, uMsg, wParam, lParam); + } + else + { + if (bUnicode) + PostMessageW(hWnd, uMsg, wParam, lParam); + else + PostMessageA(hWnd, uMsg, wParam, lParam); + } + } + + ImmLocalFree(pNewTransMsg); + ImmUnlockIMCC(pIC->hMsgBuf); + pIC->dwNumMsgBuf = 0; /* Processed */ + ImmUnlockIMC(hIMC); + + return TRUE; +} + /*********************************************************************** * CtfImmHideToolbarWnd(IMM32.@) * diff --git a/dll/win32/imm32/ime.c b/dll/win32/imm32/ime.c index d898c924570..9268b66a0a7 100644 --- a/dll/win32/imm32/ime.c +++ b/dll/win32/imm32/ime.c @@ -191,7 +191,7 @@ BOOL APIENTRY Imm32InquireIme(PIMEDPI pImeDpi) FIXME("%s: Why stub called?\n", #name); \ return (type)0; \ } -#include "imetable.h" +#include <imetable.h> #undef DEFINE_IME_ENTRY // Win: LoadIME @@ -214,7 +214,7 @@ BOOL APIENTRY Imm32LoadIME(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi) /* Populate the table by stub IME functions */ #define DEFINE_IME_ENTRY(type, name, params, optional) pImeDpi->name = Stub##name; -#include "imetable.h" +#include <imetable.h> #undef DEFINE_IME_ENTRY /* Populate the table by real IME functions */ @@ -227,7 +227,7 @@ BOOL APIENTRY Imm32LoadIME(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi) goto Failed; \ } \ } while (0); -#include "imetable.h" +#include <imetable.h> #undef DEFINE_IME_ENTRY if (Imm32InquireIme(pImeDpi)) diff --git a/dll/win32/imm32/imm32.spec b/dll/win32/imm32/imm32.spec index 8173e1e975c..bf0d216f723 100644 --- a/dll/win32/imm32/imm32.spec +++ b/dll/win32/imm32/imm32.spec @@ -2,6 +2,7 @@ @ stdcall CtfAImmDeactivate(long) @ stdcall CtfAImmIsIME(ptr) @ stdcall CtfImmDispatchDefImeMessage(ptr long ptr ptr) +@ stdcall CtfImmGenerateMessage(ptr long) @ stdcall CtfImmGetGuidAtom(ptr long ptr) @ stdcall CtfImmHideToolbarWnd() @ stdcall CtfImmIsCiceroEnabled() diff --git a/modules/rostests/winetests/imm32/imm32.c b/modules/rostests/winetests/imm32/imm32.c index 39222884f2b..e7d9c67c332 100644 --- a/modules/rostests/winetests/imm32/imm32.c +++ b/modules/rostests/winetests/imm32/imm32.c @@ -61,11 +61,13 @@ typedef struct } u; } TEST_INPUT; +#ifndef __REACTOS__ typedef struct _tagTRANSMSG { UINT message; WPARAM wParam; LPARAM lParam; } TRANSMSG, *LPTRANSMSG; +#endif static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t); diff --git a/sdk/include/ddk/immdev.h b/sdk/include/ddk/immdev.h index 8a8586b774d..b553838888f 100644 --- a/sdk/include/ddk/immdev.h +++ b/sdk/include/ddk/immdev.h @@ -238,6 +238,107 @@ typedef struct IME_STATE C_ASSERT(sizeof(IME_STATE) == 0x18); #endif +typedef struct _tagTRANSMSG +{ + UINT message; + WPARAM wParam; + LPARAM lParam; +} TRANSMSG, *PTRANSMSG, *LPTRANSMSG; + +typedef struct _tagTRANSMSGLIST +{ + UINT uMsgCount; + TRANSMSG TransMsg[ANYSIZE_ARRAY]; +} TRANSMSGLIST, *PTRANSMSGLIST, *LPTRANSMSGLIST; + +#define DEFINE_IME_ENTRY(type, name, params, extended) typedef type (WINAPI *FN_##name) params; +#include <imetable.h> +#undef DEFINE_IME_ENTRY + +typedef struct IMEDPI +{ + struct IMEDPI *pNext; + HINSTANCE hInst; + HKL hKL; + IMEINFO ImeInfo; + UINT uCodePage; + WCHAR szUIClass[16]; + DWORD cLockObj; + DWORD dwFlags; +#define DEFINE_IME_ENTRY(type, name, params, extended) FN_##name name; +#include <imetable.h> +#undef DEFINE_IME_ENTRY +} IMEDPI, *PIMEDPI; + +#ifndef _WIN64 +C_ASSERT(offsetof(IMEDPI, pNext) == 0x0); +C_ASSERT(offsetof(IMEDPI, hInst) == 0x4); +C_ASSERT(offsetof(IMEDPI, hKL) == 0x8); +C_ASSERT(offsetof(IMEDPI, ImeInfo) == 0xc); +C_ASSERT(offsetof(IMEDPI, uCodePage) == 0x28); +C_ASSERT(offsetof(IMEDPI, szUIClass) == 0x2c); +C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c); +C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50); +C_ASSERT(offsetof(IMEDPI, ImeInquire) == 0x54); +C_ASSERT(offsetof(IMEDPI, ImeConversionList) == 0x58); +C_ASSERT(offsetof(IMEDPI, ImeRegisterWord) == 0x5c); +C_ASSERT(offsetof(IMEDPI, ImeUnregisterWord) == 0x60); +C_ASSERT(offsetof(IMEDPI, ImeGetRegisterWordStyle) == 0x64); +C_ASSERT(offsetof(IMEDPI, ImeEnumRegisterWord) == 0x68); +C_ASSERT(offsetof(IMEDPI, ImeConfigure) == 0x6c); +C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70); +C_ASSERT(offsetof(IMEDPI, ImeEscape) == 0x74); +C_ASSERT(offsetof(IMEDPI, ImeProcessKey) == 0x78); +C_ASSERT(offsetof(IMEDPI, ImeSelect) == 0x7c); +C_ASSERT(offsetof(IMEDPI, ImeSetActiveContext) == 0x80); +C_ASSERT(offsetof(IMEDPI, ImeToAsciiEx) == 0x84); +C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88); +C_ASSERT(offsetof(IMEDPI, ImeSetCompositionString) == 0x8c); +C_ASSERT(offsetof(IMEDPI, ImeGetImeMenuItems) == 0x90); +C_ASSERT(offsetof(IMEDPI, CtfImeInquireExW) == 0x94); +C_ASSERT(offsetof(IMEDPI, CtfImeSelectEx) == 0x98); +C_ASSERT(offsetof(IMEDPI, CtfImeEscapeEx) == 0x9c); +C_ASSERT(offsetof(IMEDPI, CtfImeGetGuidAtom) == 0xa0); +C_ASSERT(offsetof(IMEDPI, CtfImeIsGuidMapEnable) == 0xa4); +C_ASSERT(sizeof(IMEDPI) == 0xa8); +#endif + +/* flags for IMEDPI.dwFlags */ +#define IMEDPI_FLAG_UNLOADED 0x1 +#define IMEDPI_FLAG_LOCKED 0x2 + +/* unconfirmed */ +typedef struct tagCLIENTIMC +{ + HANDLE hInputContext; /* LocalAlloc'ed LHND */ + LONG cLockObj; + DWORD dwFlags; + DWORD dwCompatFlags; + RTL_CRITICAL_SECTION cs; + UINT uCodePage; + HKL hKL; + BOOL bUnknown4; +} CLIENTIMC, *PCLIENTIMC; + +#ifndef _WIN64 +C_ASSERT(offsetof(CLIENTIMC, hInputContext) == 0x0); +C_ASSERT(offsetof(CLIENTIMC, cLockObj) == 0x4); +C_ASSERT(offsetof(CLIENTIMC, dwFlags) == 0x8); +C_ASSERT(offsetof(CLIENTIMC, dwCompatFlags) == 0xc); +C_ASSERT(offsetof(CLIENTIMC, cs) == 0x10); +C_ASSERT(offsetof(CLIENTIMC, uCodePage) == 0x28); +C_ASSERT(offsetof(CLIENTIMC, hKL) == 0x2c); +C_ASSERT(sizeof(CLIENTIMC) == 0x34); +#endif + +/* flags for CLIENTIMC */ +#define CLIENTIMC_WIDE 0x1 +#define CLIENTIMC_ACTIVE 0x2 +#define CLIENTIMC_UNKNOWN4 0x20 +#define CLIENTIMC_DESTROY 0x40 +#define CLIENTIMC_DISABLEIME 0x80 +#define CLIENTIMC_UNKNOWN2 0x100 + #ifdef __cplusplus } // extern "C" #endif diff --git a/dll/win32/imm32/CtfImeTable.h b/sdk/include/reactos/CtfImeTable.h similarity index 100% rename from dll/win32/imm32/CtfImeTable.h rename to sdk/include/reactos/CtfImeTable.h diff --git a/win32ss/include/imetable.h b/sdk/include/reactos/imetable.h similarity index 100% rename from win32ss/include/imetable.h rename to sdk/include/reactos/imetable.h diff --git a/sdk/include/reactos/imm32_undoc.h b/sdk/include/reactos/imm32_undoc.h index 61904db0b13..84d962e77c4 100644 --- a/sdk/include/reactos/imm32_undoc.h +++ b/sdk/include/reactos/imm32_undoc.h @@ -29,6 +29,7 @@ BOOL WINAPI CtfImmIsCiceroStartedInThread(VOID); VOID WINAPI CtfImmSetAppCompatFlags(_In_ DWORD dwFlags); DWORD WINAPI CtfImmHideToolbarWnd(VOID); VOID WINAPI CtfImmRestoreToolbarWnd(_In_ LPVOID pUnused, _In_ DWORD dwShowFlags); +BOOL WINAPI CtfImmGenerateMessage(_In_ HIMC hIMC, _In_ BOOL bSend); LRESULT WINAPI CtfImmDispatchDefImeMessage( diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h index 1cb0fb2db4c..f501babb00a 100644 --- a/win32ss/include/ntuser.h +++ b/win32ss/include/ntuser.h @@ -1261,107 +1261,6 @@ typedef struct _IMEWND PIMEUI pimeui; } IMEWND, *PIMEWND; -typedef struct tagTRANSMSG -{ - UINT message; - WPARAM wParam; - LPARAM lParam; -} TRANSMSG, *PTRANSMSG, *LPTRANSMSG; - -typedef struct tagTRANSMSGLIST -{ - UINT uMsgCount; - TRANSMSG TransMsg[ANYSIZE_ARRAY]; -} TRANSMSGLIST, *PTRANSMSGLIST, *LPTRANSMSGLIST; - -#define DEFINE_IME_ENTRY(type, name, params, extended) typedef type (WINAPI *FN_##name) params; -#include "imetable.h" -#undef DEFINE_IME_ENTRY - -typedef struct IMEDPI -{ - struct IMEDPI *pNext; - HINSTANCE hInst; - HKL hKL; - IMEINFO ImeInfo; - UINT uCodePage; - WCHAR szUIClass[16]; - DWORD cLockObj; - DWORD dwFlags; -#define DEFINE_IME_ENTRY(type, name, params, extended) FN_##name name; -#include "imetable.h" -#undef DEFINE_IME_ENTRY -} IMEDPI, *PIMEDPI; - -#ifndef _WIN64 -C_ASSERT(offsetof(IMEDPI, pNext) == 0x0); -C_ASSERT(offsetof(IMEDPI, hInst) == 0x4); -C_ASSERT(offsetof(IMEDPI, hKL) == 0x8); -C_ASSERT(offsetof(IMEDPI, ImeInfo) == 0xc); -C_ASSERT(offsetof(IMEDPI, uCodePage) == 0x28); -C_ASSERT(offsetof(IMEDPI, szUIClass) == 0x2c); -C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c); -C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50); -C_ASSERT(offsetof(IMEDPI, ImeInquire) == 0x54); -C_ASSERT(offsetof(IMEDPI, ImeConversionList) == 0x58); -C_ASSERT(offsetof(IMEDPI, ImeRegisterWord) == 0x5c); -C_ASSERT(offsetof(IMEDPI, ImeUnregisterWord) == 0x60); -C_ASSERT(offsetof(IMEDPI, ImeGetRegisterWordStyle) == 0x64); -C_ASSERT(offsetof(IMEDPI, ImeEnumRegisterWord) == 0x68); -C_ASSERT(offsetof(IMEDPI, ImeConfigure) == 0x6c); -C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70); -C_ASSERT(offsetof(IMEDPI, ImeEscape) == 0x74); -C_ASSERT(offsetof(IMEDPI, ImeProcessKey) == 0x78); -C_ASSERT(offsetof(IMEDPI, ImeSelect) == 0x7c); -C_ASSERT(offsetof(IMEDPI, ImeSetActiveContext) == 0x80); -C_ASSERT(offsetof(IMEDPI, ImeToAsciiEx) == 0x84); -C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88); -C_ASSERT(offsetof(IMEDPI, ImeSetCompositionString) == 0x8c); -C_ASSERT(offsetof(IMEDPI, ImeGetImeMenuItems) == 0x90); -C_ASSERT(offsetof(IMEDPI, CtfImeInquireExW) == 0x94); -C_ASSERT(offsetof(IMEDPI, CtfImeSelectEx) == 0x98); -C_ASSERT(offsetof(IMEDPI, CtfImeEscapeEx) == 0x9c); -C_ASSERT(offsetof(IMEDPI, CtfImeGetGuidAtom) == 0xa0); -C_ASSERT(offsetof(IMEDPI, CtfImeIsGuidMapEnable) == 0xa4); -C_ASSERT(sizeof(IMEDPI) == 0xa8); -#endif - -/* flags for IMEDPI.dwFlags */ -#define IMEDPI_FLAG_UNLOADED 0x1 -#define IMEDPI_FLAG_LOCKED 0x2 - -/* unconfirmed */ -typedef struct tagCLIENTIMC -{ - HANDLE hInputContext; /* LocalAlloc'ed LHND */ - LONG cLockObj; - DWORD dwFlags; - DWORD dwCompatFlags; - RTL_CRITICAL_SECTION cs; - UINT uCodePage; - HKL hKL; - BOOL bUnknown4; -} CLIENTIMC, *PCLIENTIMC; - -#ifndef _WIN64 -C_ASSERT(offsetof(CLIENTIMC, hInputContext) == 0x0); -C_ASSERT(offsetof(CLIENTIMC, cLockObj) == 0x4); -C_ASSERT(offsetof(CLIENTIMC, dwFlags) == 0x8); -C_ASSERT(offsetof(CLIENTIMC, dwCompatFlags) == 0xc); -C_ASSERT(offsetof(CLIENTIMC, cs) == 0x10); -C_ASSERT(offsetof(CLIENTIMC, uCodePage) == 0x28); -C_ASSERT(offsetof(CLIENTIMC, hKL) == 0x2c); -C_ASSERT(sizeof(CLIENTIMC) == 0x34); -#endif - -/* flags for CLIENTIMC */ -#define CLIENTIMC_WIDE 0x1 -#define CLIENTIMC_ACTIVE 0x2 -#define CLIENTIMC_UNKNOWN4 0x20 -#define CLIENTIMC_DESTROY 0x40 -#define CLIENTIMC_DISABLEIME 0x80 -#define CLIENTIMC_UNKNOWN2 0x100 - DWORD NTAPI NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags);
1 year, 1 month
1
0
0
0
[reactos] 01/01: [IMM32] Implement Soft Keyboard Type C1 (#6036)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6783061894743604dd057…
commit 6783061894743604dd057858f5ae3b1d38f238f7 Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Sat Nov 25 18:56:33 2023 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Sat Nov 25 18:56:33 2023 +0900 [IMM32] Implement Soft Keyboard Type C1 (#6036) Follow-up to #6021. This PR will finish ImmCreateSoftKeyboard implementation. - Add c1key.h to define C1 internal codes. - The tests are done, using FreeCJ2004 on Chinese/Taiwanese system. FreeCJ2004:
https://web.archive.org/web/20061208204431/http://input.foruto.com/download…
CORE-19268 --- dll/win32/imm32/c1keys.h | 64 +++ dll/win32/imm32/softkbd.c | 1029 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 1027 insertions(+), 66 deletions(-) diff --git a/dll/win32/imm32/c1keys.h b/dll/win32/imm32/c1keys.h new file mode 100644 index 00000000000..34f1ea3049e --- /dev/null +++ b/dll/win32/imm32/c1keys.h @@ -0,0 +1,64 @@ +/* + * PROJECT: ReactOS IMM32 + * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later
) + * PURPOSE: Defining internal codes (C1K_...) of IME Soft Keyboard Type C1 + * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> + */ + +/* DEFINE_C1K(c1k_code, virtual_key_code, c1k_code_name, virtual_key_name, is_special) */ +DEFINE_C1K( 0, 0xC0, C1K_OEM_3, VK_OEM_3, FALSE) +DEFINE_C1K( 1, 0x31, C1K_1, VK_1, FALSE) +DEFINE_C1K( 2, 0x32, C1K_2, VK_2, FALSE) +DEFINE_C1K( 3, 0x33, C1K_3, VK_3, FALSE) +DEFINE_C1K( 4, 0x34, C1K_4, VK_4, FALSE) +DEFINE_C1K( 5, 0x35, C1K_5, VK_5, FALSE) +DEFINE_C1K( 6, 0x36, C1K_6, VK_6, FALSE) +DEFINE_C1K( 7, 0x37, C1K_7, VK_7, FALSE) +DEFINE_C1K( 8, 0x38, C1K_8, VK_8, FALSE) +DEFINE_C1K( 9, 0x39, C1K_9, VK_9, FALSE) +DEFINE_C1K(10, 0x30, C1K_0, VK_0, FALSE) +DEFINE_C1K(11, 0xBD, C1K_OEM_MINUS, VK_OEM_MINUS, FALSE) +DEFINE_C1K(12, 0xBB, C1K_OEM_PLUS, VK_OEM_PLUS, FALSE) +DEFINE_C1K(13, 0x51, C1K_Q, VK_Q, FALSE) +DEFINE_C1K(14, 0x57, C1K_W, VK_W, FALSE) +DEFINE_C1K(15, 0x45, C1K_E, VK_E, FALSE) +DEFINE_C1K(16, 0x52, C1K_R, VK_R, FALSE) +DEFINE_C1K(17, 0x54, C1K_T, VK_T, FALSE) +DEFINE_C1K(18, 0x59, C1K_Y, VK_Y, FALSE) +DEFINE_C1K(19, 0x55, C1K_U, VK_U, FALSE) +DEFINE_C1K(20, 0x49, C1K_I, VK_I, FALSE) +DEFINE_C1K(21, 0x4F, C1K_O, VK_O, FALSE) +DEFINE_C1K(22, 0x50, C1K_P, VK_P, FALSE) +DEFINE_C1K(23, 0xDB, C1K_OEM_4, VK_OEM_4, FALSE) +DEFINE_C1K(24, 0xDD, C1K_OEM_6, VK_OEM_6, FALSE) +DEFINE_C1K(25, 0xDC, C1K_OEM_5, VK_OEM_5, FALSE) +DEFINE_C1K(26, 0x41, C1K_A, VK_A, FALSE) +DEFINE_C1K(27, 0x53, C1K_S, VK_S, FALSE) +DEFINE_C1K(28, 0x44, C1K_D, VK_D, FALSE) +DEFINE_C1K(29, 0x46, C1K_F, VK_F, FALSE) +DEFINE_C1K(30, 0x47, C1K_G, VK_G, FALSE) +DEFINE_C1K(31, 0x48, C1K_H, VK_H, FALSE) +DEFINE_C1K(32, 0x4A, C1K_J, VK_J, FALSE) +DEFINE_C1K(33, 0x4B, C1K_K, VK_K, FALSE) +DEFINE_C1K(34, 0x4C, C1K_L, VK_L, FALSE) +DEFINE_C1K(35, 0xBA, C1K_OEM_1, VK_OEM_1, FALSE) +DEFINE_C1K(36, 0xDE, C1K_OEM_7, VK_OEM_7, FALSE) +DEFINE_C1K(37, 0x5A, C1K_Z, VK_Z, FALSE) +DEFINE_C1K(38, 0x58, C1K_X, VK_X, FALSE) +DEFINE_C1K(39, 0x43, C1K_C, VK_C, FALSE) +DEFINE_C1K(40, 0x56, C1K_V, VK_V, FALSE) +DEFINE_C1K(41, 0x42, C1K_B, VK_B, FALSE) +DEFINE_C1K(42, 0x4E, C1K_N, VK_N, FALSE) +DEFINE_C1K(43, 0x4D, C1K_M, VK_M, FALSE) +DEFINE_C1K(44, 0xBC, C1K_OEM_COMMA, VK_OEM_COMMA, FALSE) +DEFINE_C1K(45, 0xBE, C1K_OEM_DOT, VK_OEM_PERIOD, FALSE) +DEFINE_C1K(46, 0xBF, C1K_OEM_2, VK_OEM_2, FALSE) +DEFINE_C1K(47, 0x08, C1K_BACKSPACE, VK_BACK, TRUE) +DEFINE_C1K(48, 0x09, C1K_TAB, VK_TAB, TRUE) +DEFINE_C1K(49, 0x14, C1K_CAPS, VK_CAPITAL, TRUE) +DEFINE_C1K(50, 0x0D, C1K_ENTER, VK_RETURN, TRUE) +DEFINE_C1K(51, 0x10, C1K_SHIFT, VK_SHIFT, TRUE) +DEFINE_C1K(52, 0x2D, C1K_INSERT, VK_INSERT, TRUE) +DEFINE_C1K(53, 0x2E, C1K_DELETE, VK_DELETE, TRUE) +DEFINE_C1K(54, 0x20, C1K_SPACE, VK_SPACE, TRUE) +DEFINE_C1K(55, 0x1B, C1K_ESCAPE, VK_ESCAPE, TRUE) diff --git a/dll/win32/imm32/softkbd.c b/dll/win32/imm32/softkbd.c index 8cf17248760..522ff99185c 100644 --- a/dll/win32/imm32/softkbd.c +++ b/dll/win32/imm32/softkbd.c @@ -32,6 +32,23 @@ Imm32PtInRect( return (x <= ppt->x) && (ppt->x < x + cx) && (y <= ppt->y) && (ppt->y < y + cy); } +static void +Imm32DrawBitmap( + _In_ HDC hdc, + _In_ INT x, + _In_ INT y, + _In_ INT width, + _In_ INT height, + _In_ INT nBitmapID) +{ + HBITMAP hBitmap = LoadBitmapW(ghImm32Inst, MAKEINTRESOURCEW(nBitmapID)); + HDC hMemDC = CreateCompatibleDC(hdc); + HGDIOBJ hbmOld = SelectObject(hMemDC, hBitmap); + BitBlt(hdc, x, y, width, height, hMemDC, 0, 0, SRCCOPY); + DeleteObject(SelectObject(hMemDC, hbmOld)); + DeleteDC(hMemDC); +} + static inline INT Imm32Clamp( _In_ INT x, @@ -320,24 +337,6 @@ T1_DrawConvexRect( PatBlt(hDC, x0 + dx - 1, y + dy - 3, -1, 2 - dy, PATCOPY); } -static void -T1_DrawBitmap( - _In_ HDC hDC, - _In_ INT x, - _In_ INT y, - _In_ INT cx, - _In_ INT cy, - _In_ INT nBitmapID) -{ - HBITMAP hBitmap = LoadBitmapW(ghImm32Inst, MAKEINTRESOURCEW(nBitmapID)); - HDC hMemDC = CreateCompatibleDC(hDC); - HGDIOBJ hbmOld = SelectObject(hMemDC, hBitmap); - BitBlt(hDC, x, y, cx, cy, hMemDC, 0, 0, SRCCOPY); - SelectObject(hMemDC, hbmOld); - DeleteObject(hBitmap); - DeleteDC(hMemDC); -} - static void T1_DrawLabels( _In_ HDC hDC, @@ -386,46 +385,46 @@ T1_InitBitmap( T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_L_CTRL).x, T1_KEYPOS(T1K_L_CTRL).y, pT1->cxWidth53or54, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_L_CTRL).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_CTRL).y - 4, - 16, 9, IDB_T1_CTRL); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_L_CTRL).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_CTRL).y - 4, + 16, 9, IDB_T1_CTRL); /* 54 --> Right [Ctrl] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_R_CTRL).x, T1_KEYPOS(T1K_R_CTRL).y, pT1->cxWidth53or54, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_R_CTRL).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_CTRL).y - 4, - 16, 9, IDB_T1_CTRL); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_R_CTRL).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_CTRL).y - 4, + 16, 9, IDB_T1_CTRL); /* 57 --> [Esc] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_ESCAPE).x, T1_KEYPOS(T1K_ESCAPE).y, pT1->cxWidth57, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth57 / 2 + T1_KEYPOS(T1K_ESCAPE).x - 9, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_ESCAPE).y - 4, - 18, 9, IDB_T1_ESCAPE); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth57 / 2 + T1_KEYPOS(T1K_ESCAPE).x - 9, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_ESCAPE).y - 4, + 18, 9, IDB_T1_ESCAPE); /* 55 --> Left [Alt] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_L_ALT).x, T1_KEYPOS(T1K_L_ALT).y, pT1->cxWidth55or56, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_L_ALT).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_ALT).y - 4, - 16, 9, IDB_T1_ALT); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_L_ALT).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_ALT).y - 4, + 16, 9, IDB_T1_ALT); /* 56 --> Right [Alt] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_R_ALT).x, T1_KEYPOS(T1K_R_ALT).y, pT1->cxWidth55or56, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_R_ALT).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_ALT).y - 4, - 16, 9, IDB_T1_ALT); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_R_ALT).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_ALT).y - 4, + 16, 9, IDB_T1_ALT); /* 58 --> [Space] */ T1_DrawConvexRect(hMemDC, @@ -436,55 +435,55 @@ T1_InitBitmap( T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_L_SHIFT).x, T1_KEYPOS(T1K_L_SHIFT).y, pT1->cxWidth51or52, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_L_SHIFT).x - 11, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_SHIFT).y - 4, - 23, 9, IDB_T1_SHIFT); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_L_SHIFT).x - 11, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_SHIFT).y - 4, + 23, 9, IDB_T1_SHIFT); /* 52 --> Right [Shift] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_R_SHIFT).x, T1_KEYPOS(T1K_R_SHIFT).y, pT1->cxWidth51or52, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_R_SHIFT).x - 11, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_SHIFT).y - 4, - 23, 9, IDB_T1_SHIFT); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_R_SHIFT).x - 11, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_SHIFT).y - 4, + 23, 9, IDB_T1_SHIFT); /* 49 --> [Caps] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_CAPS).x, T1_KEYPOS(T1K_CAPS).y, pT1->cxWidth49, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth49 / 2 + T1_KEYPOS(T1K_CAPS).x - 11, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_CAPS).y - 4, - 22, 9, IDB_T1_CAPS); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth49 / 2 + T1_KEYPOS(T1K_CAPS).x - 11, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_CAPS).y - 4, + 22, 9, IDB_T1_CAPS); /* 48 --> [Tab] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_TAB).x, T1_KEYPOS(T1K_TAB).y, pT1->cxWidth48, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth48 / 2 + T1_KEYPOS(T1K_TAB).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_TAB).y - 4, - 16, 9, IDB_T1_TAB); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth48 / 2 + T1_KEYPOS(T1K_TAB).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_TAB).y - 4, + 16, 9, IDB_T1_TAB); /* 50 --> [Enter] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_ENTER).x, T1_KEYPOS(T1K_ENTER).y, pT1->cxWidth50, pT1->cyHeight50); - T1_DrawBitmap(hMemDC, - pT1->cxWidth50 / 2 + T1_KEYPOS(T1K_ENTER).x - 13, - pT1->cyHeight50 / 2 + T1_KEYPOS(T1K_ENTER).y - 4, - 26, 9, IDB_T1_ENTER); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth50 / 2 + T1_KEYPOS(T1K_ENTER).x - 13, + pT1->cyHeight50 / 2 + T1_KEYPOS(T1K_ENTER).y - 4, + 26, 9, IDB_T1_ENTER); /* 47 --> [BackSpace] */ T1_DrawConvexRect(hMemDC, T1_KEYPOS(T1K_BACKSPACE).x, T1_KEYPOS(T1K_BACKSPACE).y, pT1->cxWidth47, pT1->cyDefHeight); - T1_DrawBitmap(hMemDC, - pT1->cxWidth47 / 2 + T1_KEYPOS(T1K_BACKSPACE).x - 8, - pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_BACKSPACE).y - 4, - 16, 9, IDB_T1_BACKSPACE); + Imm32DrawBitmap(hMemDC, + pT1->cxWidth47 / 2 + T1_KEYPOS(T1K_BACKSPACE).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_BACKSPACE).y - 4, + 16, 9, IDB_T1_BACKSPACE); /* Regular keys */ for (iKey = 0; iKey < T1K_BACKSPACE; ++iKey) @@ -842,7 +841,7 @@ T1_OnButtonUp( iPressed = pT1->PressedKey; if (iPressed >= T1K_NONE) { - if (pT1->pt1.x != -1 && pT1->pt1.y != -1 ) + if (pT1->pt1.x != -1 && pT1->pt1.y != -1) { T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1); x = pT1->pt0.x - pT1->pt1.x; @@ -1123,6 +1122,865 @@ T1_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #define C1_CLASSNAMEW L"SoftKBDClsC1" +#define C1K_MAX 56 + +#undef DEFINE_C1K +#define DEFINE_C1K(c1k_code, virtual_key_code, c1k_code_name, virtual_key_name, is_special) \ + c1k_code_name = c1k_code, + +/* Define C1 internal codes (C1K_...) */ +typedef enum C1KEY +{ +#include "c1keys.h" +} C1KEY; + +#undef DEFINE_C1K +#define DEFINE_C1K(c1k_code, virtual_key_code, c1k_code_name, virtual_key_name, is_special) \ + virtual_key_code, + +/* Mapping: C1K --> Virtual Key */ +const BYTE gC1K2VK[C1K_MAX] = +{ +#include "c1keys.h" +}; + +typedef struct C1WINDOW +{ + WCHAR Data[2][47]; + DWORD dwFlags; + HBITMAP hbmKeyboard; + LPARAM SubType; + INT iPressedKey; + POINT pt1, pt2; + DWORD CharSet; +} C1WINDOW, *PC1WINDOW; + +/* The flags for C1WINDOW.dwFlags */ +#define FLAG_SHIFT_PRESSED 1 +#define FLAG_DRAGGING 2 +#define FLAG_PRESSED 4 + +static BOOL gbC1ButtonInit = FALSE; +static POINT gptC1ButtonPos[C1K_MAX]; + +static void C1_InitButtonPos(void) +{ + LONG x = 0, y = 0; + INT iKey; + + /* 1st row */ + for (iKey = C1K_OEM_3; iKey < C1K_Q; ++iKey) + { + gptC1ButtonPos[iKey].x = x; + gptC1ButtonPos[iKey].y = y; + x += 24; + } + gptC1ButtonPos[C1K_BACKSPACE].x = x; + gptC1ButtonPos[C1K_BACKSPACE].y = y; + + /* 2nd row */ + y = 28; + gptC1ButtonPos[C1K_TAB].x = 0; + gptC1ButtonPos[C1K_TAB].y = y; + x = 36; + for (; iKey < C1K_A; ++iKey) + { + gptC1ButtonPos[iKey].x = x; + gptC1ButtonPos[iKey].y = y; + x += 24; + } + + /* 3rd row */ + y = 56; + gptC1ButtonPos[C1K_CAPS].x = 0; + gptC1ButtonPos[C1K_CAPS].y = y; + x = 42; + for (; iKey < C1K_Z; ++iKey) + { + gptC1ButtonPos[iKey].x = x; + gptC1ButtonPos[iKey].y = y; + x += 24; + } + gptC1ButtonPos[C1K_ENTER].x = x; + gptC1ButtonPos[C1K_ENTER].y = y; + + /* 4th row */ + y = 84; + gptC1ButtonPos[C1K_SHIFT].x = 0; + gptC1ButtonPos[C1K_SHIFT].y = y; + x = 60; + for (; iKey < C1K_BACKSPACE; ++iKey) + { + gptC1ButtonPos[iKey].x = x; + gptC1ButtonPos[iKey].y = y; + x += 24; + } + + /* 5th row */ + y = 112; + gptC1ButtonPos[C1K_INSERT].x = 0; + gptC1ButtonPos[C1K_INSERT].y = y; + gptC1ButtonPos[C1K_DELETE].x = 58; + gptC1ButtonPos[C1K_DELETE].y = y; + gptC1ButtonPos[C1K_SPACE].x = 96; + gptC1ButtonPos[C1K_SPACE].y = y; + gptC1ButtonPos[C1K_ESCAPE].x = 310; + gptC1ButtonPos[C1K_ESCAPE].y = y; +} + +static void +C1_DrawConvexRect( + _In_ HDC hDC, + _In_ INT x, + _In_ INT y, + _In_ INT width, + _In_ INT height) +{ + HGDIOBJ hLtGrayBrush = GetStockObject(LTGRAY_BRUSH); + HGDIOBJ hBlackPen = GetStockObject(BLACK_PEN); + HGDIOBJ hWhiteBrush = GetStockObject(WHITE_BRUSH); + HGDIOBJ hGrayBrush = GetStockObject(GRAY_BRUSH); + INT y2 = y + height - 1; + + /* Draw face */ + SelectObject(hDC, hLtGrayBrush); + SelectObject(hDC, hBlackPen); + Rectangle(hDC, x, y, x + width, y + height); + + /* Draw light edge */ + SelectObject(hDC, hWhiteBrush); + PatBlt(hDC, x, y2, 2, 1 - height, PATCOPY); + PatBlt(hDC, x, y, width - 1, 2, PATCOPY); + + /* Draw dark edge */ + SelectObject(hDC, hGrayBrush); + PatBlt(hDC, x + 1, y2, width - 2, -1, PATCOPY); + PatBlt(hDC, x + width - 1, y2, -1, 2 - height, PATCOPY); +} + +static void +C1_InvertButton( + _In_ HDC hDC, + _In_ INT iKey) +{ + INT width = 24, height = 28; + + if (iKey < 0) + return; + + switch (iKey) + { + case C1K_BACKSPACE: case C1K_TAB: + width = 36; + break; + case C1K_CAPS: case C1K_ENTER: + width = 42; + break; + case C1K_SHIFT: + width = 60; + break; + case C1K_INSERT: case C1K_DELETE: case C1K_ESCAPE: + width = 38; + height = 24; + break; + case C1K_SPACE: + width = 172; + height = 24; + break; + default: + break; + } + + BitBlt(hDC, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, width, height, + hDC, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, DSTINVERT); +} + +static void +C1_DrawLabel( + _In_ HDC hDC, + _In_ INT nBitmapID) +{ + HBITMAP hBitmap; + HGDIOBJ hbmOld; + HDC hMemDC; + INT iKey; + + hBitmap = LoadBitmapW(ghImm32Inst, MAKEINTRESOURCEW(nBitmapID)); + hMemDC = CreateCompatibleDC(hDC); + hbmOld = SelectObject(hMemDC, hBitmap); + for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey) + { + BitBlt(hDC, gptC1ButtonPos[iKey].x + 2, gptC1ButtonPos[iKey].y + 2, 8, 8, + hMemDC, iKey * 8, 0, SRCCOPY); + } + DeleteObject(SelectObject(hMemDC, hbmOld)); + DeleteDC(hMemDC); +} + +static void +C1_InitBitmap( + _In_ HDC hDC, + _In_ INT x, + _In_ INT y, + _In_ INT width, + _In_ INT height) +{ + HGDIOBJ hLtGrayBrush = GetStockObject(LTGRAY_BRUSH); + HGDIOBJ hNullPen = GetStockObject(NULL_PEN); + INT iKey; + + /* Draw keyboard frame */ + SelectObject(hDC, hLtGrayBrush); + SelectObject(hDC, hNullPen); + Rectangle(hDC, x, y, width + 1, height + 1); + + for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey) + { + C1_DrawConvexRect(hDC, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, 24, 28); + } + + C1_DrawLabel(hDC, IDB_C1_CHARS); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_BACKSPACE].x, gptC1ButtonPos[C1K_BACKSPACE].y, 36, 28); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_BACKSPACE].x + 2, gptC1ButtonPos[C1K_BACKSPACE].y + 2, 32, 24, IDB_C1_BACKSPACE); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_TAB].x, gptC1ButtonPos[C1K_TAB].y, 36, 28); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_TAB].x + 2, gptC1ButtonPos[C1K_TAB].y + 2, 32, 24, IDB_C1_TAB); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_CAPS].x, gptC1ButtonPos[C1K_CAPS].y, 42, 28); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_CAPS].x + 2, gptC1ButtonPos[C1K_CAPS].y + 2, 38, 24, IDB_C1_CAPS); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_ENTER].x, gptC1ButtonPos[C1K_ENTER].y, 42, 28); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_ENTER].x + 2, gptC1ButtonPos[C1K_ENTER].y + 2, 38, 24, IDB_C1_ENTER); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_SHIFT].x, gptC1ButtonPos[C1K_SHIFT].y, 60, 28); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_SHIFT].x + 2, gptC1ButtonPos[C1K_SHIFT].y + 2, 56, 24, IDB_C1_SHIFT); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_INSERT].x, gptC1ButtonPos[C1K_INSERT].y, 38, 24); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_INSERT].x + 2, gptC1ButtonPos[C1K_INSERT].y + 2, 34, 20, IDB_C1_INS); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_DELETE].x, gptC1ButtonPos[C1K_DELETE].y, 38, 24); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_DELETE].x + 2, gptC1ButtonPos[C1K_DELETE].y + 2, 34, 20, IDB_C1_DEL); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_SPACE].x, gptC1ButtonPos[C1K_SPACE].y, 172, 24); + + C1_DrawConvexRect(hDC, gptC1ButtonPos[C1K_ESCAPE].x, gptC1ButtonPos[C1K_ESCAPE].y , 38, 24); + Imm32DrawBitmap(hDC, gptC1ButtonPos[C1K_ESCAPE].x + 2, gptC1ButtonPos[C1K_ESCAPE].y + 2, 34, 20, IDB_C1_ESCAPE); +} + +static INT +C1_OnCreate( + _In_ HWND hWnd) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HDC hDC, hMemDC; + RECT rc; + HGDIOBJ hbmOld; + HBITMAP hbmKeyboard; + + hGlobal = GlobalAlloc(GHND, sizeof(C1WINDOW)); + if (!hGlobal) + return -1; + + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!pC1) + { + GlobalFree(hGlobal); + return -1; + } + SetWindowLongPtrW(hWnd, 0, (LONG_PTR)hGlobal); + + if (!gbC1ButtonInit) + { + C1_InitButtonPos(); + gbC1ButtonInit = TRUE; + } + + pC1->iPressedKey = -1; + pC1->CharSet = GB2312_CHARSET; + + GetClientRect(hWnd, &rc); + + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + hbmKeyboard = CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top); + ReleaseDC(hWnd, hDC); + + hbmOld = SelectObject(hMemDC, hbmKeyboard); + C1_InitBitmap(hMemDC, rc.left, rc.top, rc.right, rc.bottom); + SelectObject(hMemDC, hbmOld); + pC1->hbmKeyboard = hbmKeyboard; + DeleteDC(hMemDC); + + GlobalUnlock(hGlobal); + return 0; +} + +static void +C1_OnDraw( + _In_ HDC hDC, + _In_ HWND hWnd) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HDC hMemDC; + RECT rc; + HGDIOBJ hbmOld; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return; + + GetClientRect(hWnd, &rc); + + hMemDC = CreateCompatibleDC(hDC); + hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard); + BitBlt(hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 0, 0, SRCCOPY); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + + GlobalUnlock(hGlobal); +} + +static BOOL +C1_SetData( + _In_ HWND hWnd, + _In_ const SOFTKBDDATA *pData) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HDC hDC, hMemDC; + INT iKey; + BOOL bDisabled; + HBITMAP hbmKeyboard; + HGDIOBJ hbmOld, hFontOld; + HFONT hFont; + RECT rc; + LOGFONTW lf; + + if (pData->uCount != 2) + return 0; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return FALSE; + + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + + hbmKeyboard = pC1->hbmKeyboard; + hbmOld = SelectObject(hMemDC, hbmKeyboard); + + GetObjectW(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf); + lf.lfHeight = -12; + if (pC1->CharSet != DEFAULT_CHARSET) + lf.lfCharSet = (BYTE)pC1->CharSet; + + hFont = CreateFontIndirectW(&lf); + hFontOld = SelectObject(hMemDC, hFont); + for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey) + { + pC1->Data[1][iKey] = pData->wCode[0][(BYTE)gC1K2VK[iKey]]; + pC1->Data[0][iKey] = pData->wCode[1][(BYTE)gC1K2VK[iKey]]; + } + + SetBkColor(hMemDC, RGB(191, 191, 191)); + for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey) + { + /* Upper right */ + rc.right = gptC1ButtonPos[iKey].x + 24 - 2; + rc.top = gptC1ButtonPos[iKey].y + 2; + rc.left = rc.right - 14; + rc.bottom = rc.top + 14; + bDisabled = (pC1->Data[0][iKey] == 0); + DrawTextW(hMemDC, &pC1->Data[0][iKey], !bDisabled, &rc, + DT_RIGHT | DT_TOP | DT_SINGLELINE); + + /* Lower left */ + rc.left = gptC1ButtonPos[iKey].x + 2; + rc.bottom = gptC1ButtonPos[iKey].y + 28 - 2; + rc.right = rc.left + 14; + rc.top = rc.bottom - 14; + bDisabled = (pC1->Data[1][iKey] == 0); + DrawTextW(hMemDC, &pC1->Data[1][iKey], !bDisabled, &rc, + DT_LEFT | DT_BOTTOM | DT_SINGLELINE); + } + + if (pC1->dwFlags & FLAG_SHIFT_PRESSED) + C1_InvertButton(hMemDC, C1K_SHIFT); + + pC1->dwFlags = 0; + + SelectObject(hMemDC, hbmOld); + DeleteObject(SelectObject(hMemDC, hFontOld)); + + DeleteDC(hMemDC); + ReleaseDC(hWnd, hDC); + + GlobalUnlock(hGlobal); + return TRUE; +} + +static void +C1_DrawDragBorder( + _In_ HWND hWnd, + _In_ LPPOINT ppt1, + _Inout_ LPPOINT ppt2) +{ + HGDIOBJ hGrayBrush = GetStockObject(GRAY_BRUSH); + INT x, y; + RECT rc, rcWork; + INT cxBorder = GetSystemMetrics(SM_CXBORDER), cyBorder = GetSystemMetrics(SM_CYBORDER); + HDC hDisplayDC; + + Imm32GetAllMonitorSize(&rcWork); + hDisplayDC = CreateDCW(L"DISPLAY", NULL, NULL, NULL); + + SelectObject(hDisplayDC, hGrayBrush); + x = ppt1->x - ppt2->x; + y = ppt1->y - ppt2->y; + if (x < rcWork.left) + x = rcWork.left; + if (y < rcWork.top) + y = rcWork.top; + + GetWindowRect(hWnd, &rc); + + if (rc.right - rc.left + x > rcWork.right) + x = rc.left + rcWork.right - rc.right; + if (y + rc.bottom - rc.top > rcWork.bottom) + y = rc.top + rcWork.bottom - rc.bottom; + + ppt2->x = ppt1->x - x; + ppt2->y = ppt1->y - y; + + PatBlt(hDisplayDC, x, y, rc.right - rc.left - cxBorder, cyBorder, PATINVERT); + PatBlt(hDisplayDC, x, y + cyBorder, cxBorder, rc.bottom - rc.top - cyBorder, PATINVERT); + PatBlt(hDisplayDC, x + cxBorder, y + rc.bottom - rc.top, rc.right - rc.left - cxBorder, -cyBorder, PATINVERT); + PatBlt(hDisplayDC, x + rc.right - rc.left, y, -cxBorder, rc.bottom - rc.top - cyBorder, PATINVERT); + + DeleteDC(hDisplayDC); +} + +static INT +C1_HitTest( + _In_ const POINT *ppt) +{ + INT iKey; + + for (iKey = C1K_OEM_3; iKey < C1K_BACKSPACE; ++iKey) + { + if (Imm32PtInRect(ppt, gptC1ButtonPos[iKey].x, gptC1ButtonPos[iKey].y, 24, 28)) + return iKey; + } + + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_BACKSPACE].x, gptC1ButtonPos[C1K_BACKSPACE].y, 36, 28)) + return C1K_BACKSPACE; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_TAB].x, gptC1ButtonPos[C1K_TAB].y, 36, 28)) + return C1K_TAB; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_CAPS].x, gptC1ButtonPos[C1K_CAPS].y, 42, 28)) + return C1K_CAPS; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_ENTER].x, gptC1ButtonPos[C1K_ENTER].y, 42, 28)) + return C1K_ENTER; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_SHIFT].x, gptC1ButtonPos[C1K_SHIFT].y, 60, 28)) + return C1K_SHIFT; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_ESCAPE].x, gptC1ButtonPos[C1K_ESCAPE].y, 38, 24)) + return C1K_ESCAPE; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_SPACE].x, gptC1ButtonPos[C1K_SPACE].y, 172, 24)) + return C1K_SPACE; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_INSERT].x, gptC1ButtonPos[C1K_INSERT].y, 38, 24)) + return C1K_INSERT; + if (Imm32PtInRect(ppt, gptC1ButtonPos[C1K_DELETE].x, gptC1ButtonPos[C1K_DELETE].y, 38, 24)) + return C1K_DELETE; + + return -1; +} + +static void +C1_OnButtonDown( + _In_ HWND hWnd, + _Inout_ PC1WINDOW pC1) +{ + INT iPressedKey; + HDC hMemDC; + WCHAR wch = 0xFF; + HGDIOBJ hbmOld; + HDC hDC; + + SetCapture(hWnd); + + iPressedKey = pC1->iPressedKey; + if (iPressedKey == -1) + { + pC1->dwFlags |= FLAG_DRAGGING; + C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2); + return; + } + + if (iPressedKey < C1K_BACKSPACE) + { + wch = pC1->Data[!(pC1->dwFlags & 1)][iPressedKey]; + if (!wch) + { + MessageBeep(0xFFFFFFFF); + pC1->iPressedKey = -1; + return; + } + } + + if ((iPressedKey != C1K_SHIFT) || !(pC1->dwFlags & FLAG_SHIFT_PRESSED)) + { + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard); + C1_InvertButton(hDC, pC1->iPressedKey); + C1_InvertButton(hMemDC, pC1->iPressedKey); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + ReleaseDC(hWnd, hDC); + } + + pC1->dwFlags |= FLAG_PRESSED; +} + +static BOOL +C1_OnSetCursor( + _In_ HWND hWnd, + _In_ LPARAM lParam) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HCURSOR hCursor; + INT iKey; + POINT pt1, pt2; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return FALSE; + + if (pC1->dwFlags & FLAG_DRAGGING) + { + hCursor = LoadCursorW(0, (LPCWSTR)IDC_SIZEALL); + SetCursor(hCursor); + GlobalUnlock(hGlobal); + return TRUE; + } + + GetCursorPos(&pt1); + pt2 = pt1; + ScreenToClient(hWnd, &pt2); + + iKey = C1_HitTest(&pt2); + if (iKey == -1) + hCursor = LoadCursorW(0, (LPCWSTR)IDC_SIZEALL); + else + hCursor = LoadCursorW(0, (LPCWSTR)IDC_HAND); + SetCursor(hCursor); + + if (HIWORD(lParam) == WM_LBUTTONDOWN) + { + pC1->pt1 = pt1; + pC1->pt2 = pt2; + pC1->iPressedKey = iKey; + C1_OnButtonDown(hWnd, pC1); + } + + GlobalUnlock(hGlobal); + return TRUE; +} + +static BOOL +C1_OnMouseMove( + _In_ HWND hWnd, + _In_ WPARAM wParam, + _In_ LPARAM lParam) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HDC hMemDC; + DWORD dwFlags; + INT iPressedKey; + POINT pt; + HGDIOBJ hbmOld; + HDC hDC; + INT iKey; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return FALSE; + + if (pC1->dwFlags & FLAG_DRAGGING) + { + C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2); + GetCursorPos(&pC1->pt1); + C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2); + GlobalUnlock(hGlobal); + return TRUE; + } + + if (pC1->iPressedKey != -1) + { + GetCursorPos(&pt); + ScreenToClient(hWnd, &pt); + iKey = C1_HitTest(&pt); + + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard); + dwFlags = pC1->dwFlags; + + iPressedKey = pC1->iPressedKey; + if (!!(dwFlags & FLAG_PRESSED) == (iKey != iPressedKey)) + { + if (iPressedKey != C1K_SHIFT || !(dwFlags & FLAG_SHIFT_PRESSED)) + { + C1_InvertButton(hDC, iPressedKey); + C1_InvertButton(hMemDC, pC1->iPressedKey); + } + + pC1->dwFlags ^= FLAG_PRESSED; + } + + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + ReleaseDC(hWnd, hDC); + } + + GlobalUnlock(hGlobal); + return TRUE; +} + +static BOOL +C1_OnButtonUp( + _In_ HWND hWnd, + _In_ WPARAM wParam, + _In_ LPARAM lParam) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + BOOL ret = FALSE; + INT x, y, iKey; + HDC hDC, hMemDC; + HGDIOBJ hbmOld; + HIMC hIMC; + HWND hwndOwner; + LPINPUTCONTEXT pIC; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return FALSE; + + ReleaseCapture(); + + if (pC1->dwFlags & FLAG_DRAGGING) + { + pC1->dwFlags &= ~FLAG_DRAGGING; + C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2); + x = pC1->pt1.x - pC1->pt2.x; + y = pC1->pt1.y - pC1->pt2.y; + SetWindowPos(hWnd, 0, x, y, 0, 0, 0x15u); + ret = TRUE; + + hwndOwner = GetWindow(hWnd, GW_OWNER); + hIMC = (HIMC)GetWindowLongPtrW(hwndOwner, 0); + if (hIMC) + { + pIC = ImmLockIMC(hIMC); + if (pIC) + { + pIC->fdwInit |= INIT_SOFTKBDPOS; + pIC->ptSoftKbdPos.x = x; + pIC->ptSoftKbdPos.y = y; + ImmUnlockIMC(hIMC); + } + } + + GlobalUnlock(hGlobal); + return ret; + } + + iKey = pC1->iPressedKey; + if (iKey == -1) + return FALSE; + + if (!(pC1->dwFlags & FLAG_PRESSED)) + { + pC1->iPressedKey = -1; + GlobalUnlock(hGlobal); + return ret; + } + + if (iKey == C1K_SHIFT) + { + if (!(pC1->dwFlags & FLAG_SHIFT_PRESSED)) + { + pC1->dwFlags |= FLAG_SHIFT_PRESSED; + pC1->dwFlags &= ~FLAG_PRESSED; + pC1->iPressedKey = -1; + GlobalUnlock(hGlobal); + return ret; + } + } + else if (iKey < C1K_BACKSPACE && (pC1->dwFlags & FLAG_SHIFT_PRESSED)) + { + INT iVK = gC1K2VK[pC1->iPressedKey]; + keybd_event(VK_SHIFT, guScanCode[C1K_SHIFT], 0, 0); + keybd_event(iVK, guScanCode[(BYTE)iVK], 0, 0); + keybd_event(iVK, guScanCode[(BYTE)iVK], KEYEVENTF_KEYUP, 0); + keybd_event(VK_SHIFT, guScanCode[C1K_SHIFT], KEYEVENTF_KEYUP, 0); + } + else + { + INT iVK = gC1K2VK[iKey]; + keybd_event(iVK, guScanCode[iVK], 0, 0); + keybd_event(iVK, guScanCode[iVK], KEYEVENTF_KEYUP, 0); + } + + ret = TRUE; + + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + hbmOld = SelectObject(hMemDC, pC1->hbmKeyboard); + + C1_InvertButton(hDC, pC1->iPressedKey); + C1_InvertButton(hMemDC, pC1->iPressedKey); + + if (pC1->iPressedKey < C1K_BACKSPACE && (pC1->dwFlags & FLAG_SHIFT_PRESSED)) + { + C1_InvertButton(hDC, C1K_SHIFT); + C1_InvertButton(hMemDC, C1K_SHIFT); + } + + if (pC1->iPressedKey < C1K_BACKSPACE || pC1->iPressedKey == C1K_SHIFT) + pC1->dwFlags &= ~FLAG_SHIFT_PRESSED; + + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + ReleaseDC(hWnd, hDC); + + pC1->dwFlags &= ~FLAG_PRESSED; + pC1->iPressedKey = -1; + GlobalUnlock(hGlobal); + return ret; +} + +static void +C1_OnDestroy( + _In_ HWND hWnd) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + HWND hwndOwner; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return; + + if (pC1->dwFlags & FLAG_DRAGGING) + C1_DrawDragBorder(hWnd, &pC1->pt1, &pC1->pt2); + + DeleteObject(pC1->hbmKeyboard); + GlobalUnlock(hGlobal); + GlobalFree(hGlobal); + + hwndOwner = GetWindow(hWnd, GW_OWNER); + if (hwndOwner) + SendMessageW(hwndOwner, WM_IME_NOTIFY, IMN_SOFTKBDDESTROYED, 0); +} + +static LRESULT +C1_OnImeControl( + _In_ HWND hWnd, + _In_ WPARAM wParam, + _In_ LPARAM lParam) +{ + HGLOBAL hGlobal; + PC1WINDOW pC1; + LOGFONTW lf; + RECT rc; + LRESULT ret = 0; + HDC hDC; + + switch (wParam) + { + case IMC_GETSOFTKBDFONT: + { + TRACE("IMC_GETSOFTKBDFONT: %p\n", lParam); + hDC = GetDC(hWnd); + GetObjectW(GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONTW), &lf); + ReleaseDC(hWnd, hDC); + *(LPLOGFONTW)lParam = lf; + break; + } + case IMC_SETSOFTKBDFONT: + { + LPLOGFONTW plf = (LPLOGFONTW)lParam; + LOGFONTW lf; + TRACE("IMC_SETSOFTKBDFONT: %p\n", lParam); + GetObjectW(GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONTW), &lf); + if (lf.lfCharSet == plf->lfCharSet) + return 0; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return 1; + + pC1->CharSet = plf->lfCharSet; + GlobalUnlock(hGlobal); + break; + } + case IMC_GETSOFTKBDPOS: + { + TRACE("IMC_GETSOFTKBDPOS\n"); + GetWindowRect(hWnd, &rc); + return MAKELRESULT(rc.left, rc.top); + } + case IMC_SETSOFTKBDPOS: + { + POINT pt; + POINTSTOPOINT(pt, lParam); + TRACE("IMC_SETSOFTKBDPOS: %d, %d\n", pt.x, pt.y); + SetWindowPos(hWnd, NULL, pt.x, pt.y, 0, 0, + (SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE)); + break; + } + case IMC_GETSOFTKBDSUBTYPE: + case IMC_SETSOFTKBDSUBTYPE: + { + TRACE("IMC_GETSOFTKBDSUBTYPE/IMC_SETSOFTKBDSUBTYPE: %p, %p\n", wParam, lParam); + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pC1 = (PC1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pC1) + return -1; + ret = pC1->SubType; + if (wParam == IMC_SETSOFTKBDSUBTYPE) + pC1->SubType = lParam; + GlobalUnlock(hGlobal); + break; + } + case IMC_SETSOFTKBDDATA: + { + TRACE("IMC_SETSOFTKBDDATA: %p\n", lParam); + if (C1_SetData(hWnd, (SOFTKBDDATA*)lParam)) + return -1; + + InvalidateRect(hWnd, 0, 0); + } + default: + break; + } + + return ret; +} + static LRESULT CALLBACK C1_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -1130,10 +1988,47 @@ C1_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { case WM_CREATE: { - FIXME("stub\n"); - return -1; + return C1_OnCreate(hWnd); + } + case WM_DESTROY: + { + C1_OnDestroy(hWnd); + break; + } + case WM_SETCURSOR: + { + if (C1_OnSetCursor(hWnd, lParam)) + break; + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + case WM_MOUSEMOVE: + { + if (C1_OnMouseMove(hWnd, wParam, lParam)) + break; + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + case WM_LBUTTONUP: + { + if (C1_OnButtonUp(hWnd, wParam, lParam)) + break; + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + C1_OnDraw(hDC, hWnd); + EndPaint(hWnd, &ps); + break; + } + case WM_IME_CONTROL: + { + return C1_OnImeControl(hWnd, wParam, lParam); + } + case WM_MOUSEACTIVATE: + { + return MA_NOACTIVATE; } - default: { return DefWindowProcW(hWnd, uMsg, wParam, lParam); @@ -1218,6 +2113,8 @@ ImmCreateSoftKeyboard( LPCWSTR pszClass; RECT rcWorkArea; + TRACE("(%u, %p, %d, %d)\n", uType, hwndParent, x, y); + if ((uType != SOFTKEYBOARD_TYPE_T1) && (uType != SOFTKEYBOARD_TYPE_C1)) { ERR("uType: %u\n", uType);
1 year, 1 month
1
0
0
0
[reactos] 01/01: [MSPAINT] mouse.cpp: Renaming some items for human readability
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3799d37a48340c83206e9…
commit 3799d37a48340c83206e90c2789b19c6da662bfa Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Sat Nov 25 14:14:14 2023 +0900 Commit: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> CommitDate: Sat Nov 25 14:14:14 2023 +0900 [MSPAINT] mouse.cpp: Renaming some items for human readability CORE-19094 --- base/applications/mspaint/mouse.cpp | 150 ++++++++++++++++----------------- base/applications/mspaint/toolsmodel.h | 1 - 2 files changed, 75 insertions(+), 76 deletions(-) diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp index af8fb48ab25..083467b0eb1 100644 --- a/base/applications/mspaint/mouse.cpp +++ b/base/applications/mspaint/mouse.cpp @@ -9,11 +9,11 @@ #include "precomp.h" #include <atlalloc.h> -static SIZE_T s_pointSP = 0; -static CHeapPtr<POINT, CLocalAllocator> s_pointsAllocated; -static POINT s_staticPointStack[512]; // 512 is enough -static SIZE_T s_maxPointSP = _countof(s_staticPointStack); -static LPPOINT s_pointStack = s_staticPointStack; +static SIZE_T s_cPoints = 0; +static CHeapPtr<POINT, CLocalAllocator> s_dynamicPoints; +static POINT s_staticPoints[512]; // 512 is enough +static SIZE_T s_maxPoints = _countof(s_staticPoints); +static LPPOINT s_pPoints = s_staticPoints; static POINT g_ptStart, g_ptEnd; /* FUNCTIONS ********************************************************/ @@ -53,7 +53,7 @@ BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1) return (abs(x1 - x0) <= cxThreshold) && (abs(y1 - y0) <= cyThreshold); } -void getBoundaryOfPtStack(RECT& rcBoundary, SIZE_T cPoints, const POINT *pPoints) +void getBoundaryOfPoints(RECT& rcBoundary, SIZE_T cPoints, const POINT *pPoints) { POINT ptMin = { MAXLONG, MAXLONG }, ptMax = { (LONG)MINLONG, (LONG)MINLONG }; while (cPoints-- > 0) @@ -71,22 +71,22 @@ void getBoundaryOfPtStack(RECT& rcBoundary, SIZE_T cPoints, const POINT *pPoints rcBoundary = rc; } -void ShiftPtStack(INT dx, INT dy) +void ShiftPoints(INT dx, INT dy) { - for (SIZE_T i = 0; i < s_pointSP; ++i) + for (SIZE_T i = 0; i < s_cPoints; ++i) { - POINT& pt = s_pointStack[i]; + POINT& pt = s_pPoints[i]; pt.x += dx; pt.y += dy; } } -void BuildMaskFromPtStack() +void BuildMaskFromPoints() { CRect rc; - getBoundaryOfPtStack(rc, s_pointSP, s_pointStack); + getBoundaryOfPoints(rc, s_cPoints, s_pPoints); - ShiftPtStack(-rc.left, -rc.top); + ShiftPoints(-rc.left, -rc.top); HDC hdcMem = ::CreateCompatibleDC(NULL); HBITMAP hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL); @@ -94,7 +94,7 @@ void BuildMaskFromPtStack() ::FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH)); HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN)); HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH)); - ::Polygon(hdcMem, s_pointStack, (INT)s_pointSP); + ::Polygon(hdcMem, s_pPoints, (INT)s_cPoints); ::SelectObject(hdcMem, hbrOld); ::SelectObject(hdcMem, hPenOld); ::SelectObject(hdcMem, hbmOld); @@ -105,14 +105,14 @@ void BuildMaskFromPtStack() void ToolBase::reset() { - if (s_pointStack != s_staticPointStack) + if (s_pPoints != s_staticPoints) { - s_pointsAllocated.Free(); - s_pointStack = s_staticPointStack; - s_maxPointSP = _countof(s_staticPointStack); + s_dynamicPoints.Free(); + s_pPoints = s_staticPoints; + s_maxPoints = _countof(s_staticPoints); } - s_pointSP = 0; + s_cPoints = 0; g_ptEnd = g_ptStart = { -1, -1 }; if (selectionModel.m_bShow) @@ -140,26 +140,26 @@ void ToolBase::endEvent() m_hdc = NULL; } -void ToolBase::pushToPtStack(LONG x, LONG y) +static void pushToPoints(LONG x, LONG y) { - if (s_pointSP + 1 >= s_maxPointSP) + if (s_cPoints + 1 >= s_maxPoints) { - SIZE_T newMax = s_maxPointSP + 512; + SIZE_T newMax = s_maxPoints + 512; SIZE_T cbNew = newMax * sizeof(POINT); - if (!s_pointsAllocated.ReallocateBytes(cbNew)) + if (!s_dynamicPoints.ReallocateBytes(cbNew)) { - ATLTRACE("%d, %d, %d\n", (INT)s_pointSP, (INT)s_maxPointSP, (INT)cbNew); + ATLTRACE("%d, %d, %d\n", (INT)s_cPoints, (INT)s_maxPoints, (INT)cbNew); return; } - if (s_pointStack == s_staticPointStack) - CopyMemory(s_pointsAllocated, s_staticPointStack, s_pointSP * sizeof(POINT)); + if (s_pPoints == s_staticPoints) + CopyMemory(s_dynamicPoints, s_staticPoints, s_cPoints * sizeof(POINT)); - s_pointStack = s_pointsAllocated; - s_maxPointSP = newMax; + s_pPoints = s_dynamicPoints; + s_maxPoints = newMax; } - s_pointStack[s_pointSP++] = { x, y }; + s_pPoints[s_cPoints++] = { x, y }; } /* TOOLS ********************************************************/ @@ -312,9 +312,9 @@ struct SmoothDrawTool : ToolBase m_direction = NO_DIRECTION; m_bShiftDown = (::GetKeyState(VK_SHIFT) & 0x8000); // Is Shift key pressed? m_bLeftButton = bLeftButton; - s_pointSP = 0; - pushToPtStack(x, y); - pushToPtStack(x, y); // We have to draw the first point + s_cPoints = 0; + pushToPoints(x, y); + pushToPoints(x, y); // We have to draw the first point imageModel.NotifyImageChanged(); } @@ -322,7 +322,7 @@ struct SmoothDrawTool : ToolBase { if (!m_bShiftDown) { - pushToPtStack(x, y); + pushToPoints(x, y); imageModel.NotifyImageChanged(); return TRUE; } @@ -335,7 +335,7 @@ struct SmoothDrawTool : ToolBase } RestrictDrawDirection(m_direction, g_ptStart.x, g_ptStart.y, x, y); - pushToPtStack(x, y); + pushToPoints(x, y); imageModel.NotifyImageChanged(); return TRUE; } @@ -345,10 +345,10 @@ struct SmoothDrawTool : ToolBase if (m_bShiftDown && m_direction != NO_DIRECTION) RestrictDrawDirection(m_direction, g_ptStart.x, g_ptStart.y, x, y); - pushToPtStack(x, y); + pushToPoints(x, y); CRect rcPartial; - getBoundaryOfPtStack(rcPartial, s_pointSP, s_pointStack); + getBoundaryOfPoints(rcPartial, s_cPoints, s_pPoints); SIZE size = toolsModel.GetToolSize(); rcPartial.InflateRect((size.cx + 1) / 2, (size.cy + 1) / 2); @@ -363,9 +363,9 @@ struct SmoothDrawTool : ToolBase void OnDrawOverlayOnImage(HDC hdc) override { - for (SIZE_T i = 1; i < s_pointSP; ++i) + for (SIZE_T i = 1; i < s_cPoints; ++i) { - OnDraw(hdc, m_bLeftButton, s_pointStack[i - 1], s_pointStack[i]); + OnDraw(hdc, m_bLeftButton, s_pPoints[i - 1], s_pPoints[i]); } } }; @@ -446,8 +446,8 @@ struct SelectionBaseTool : ToolBase } else { - s_pointSP = 0; - pushToPtStack(pt.x, pt.y); + s_cPoints = 0; + pushToPoints(pt.x, pt.y); } imageModel.NotifyImageChanged(); @@ -478,7 +478,7 @@ struct SelectionBaseTool : ToolBase if (isRectSelect()) selectionModel.SetRectFromPoints(g_ptStart, pt); else - pushToPtStack(pt.x, pt.y); + pushToPoints(pt.x, pt.y); imageModel.NotifyImageChanged(); return TRUE; @@ -515,14 +515,14 @@ struct SelectionBaseTool : ToolBase } else { - if (s_pointSP > 2) + if (s_cPoints > 2) { - BuildMaskFromPtStack(); + BuildMaskFromPoints(); selectionModel.m_bShow = TRUE; } else { - s_pointSP = 0; + s_cPoints = 0; selectionModel.m_bShow = FALSE; } } @@ -560,7 +560,7 @@ struct FreeSelTool : SelectionBaseTool if (!selectionModel.m_bShow && m_bDrawing) { /* Draw the freehand selection inverted/xored */ - Poly(hdc, s_pointStack, (INT)s_pointSP, 0, 0, 2, 0, FALSE, TRUE); + Poly(hdc, s_pPoints, (INT)s_cPoints, 0, 0, 2, 0, FALSE, TRUE); } } }; @@ -911,17 +911,17 @@ struct BezierTool : ToolBase void OnDrawOverlayOnImage(HDC hdc) { COLORREF rgb = (m_bLeftButton ? m_fg : m_bg); - switch (s_pointSP) + switch (s_cPoints) { case 2: - Line(hdc, s_pointStack[0].x, s_pointStack[0].y, s_pointStack[1].x, s_pointStack[1].y, rgb, + Line(hdc, s_pPoints[0].x, s_pPoints[0].y, s_pPoints[1].x, s_pPoints[1].y, rgb, toolsModel.GetLineWidth()); break; case 3: - Bezier(hdc, s_pointStack[0], s_pointStack[2], s_pointStack[2], s_pointStack[1], rgb, toolsModel.GetLineWidth()); + Bezier(hdc, s_pPoints[0], s_pPoints[2], s_pPoints[2], s_pPoints[1], rgb, toolsModel.GetLineWidth()); break; case 4: - Bezier(hdc, s_pointStack[0], s_pointStack[2], s_pointStack[3], s_pointStack[1], rgb, toolsModel.GetLineWidth()); + Bezier(hdc, s_pPoints[0], s_pPoints[2], s_pPoints[3], s_pPoints[1], rgb, toolsModel.GetLineWidth()); break; } } @@ -930,14 +930,14 @@ struct BezierTool : ToolBase { m_bLeftButton = bLeftButton; - if (s_pointSP == 0) + if (s_cPoints == 0) { - pushToPtStack(x, y); - pushToPtStack(x, y); + pushToPoints(x, y); + pushToPoints(x, y); } else { - s_pointStack[s_pointSP - 1] = { x, y }; + s_pPoints[s_cPoints - 1] = { x, y }; } imageModel.NotifyImageChanged(); @@ -945,27 +945,27 @@ struct BezierTool : ToolBase BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override { - if (s_pointSP > 0) - s_pointStack[s_pointSP - 1] = { x, y }; + if (s_cPoints > 0) + s_pPoints[s_cPoints - 1] = { x, y }; imageModel.NotifyImageChanged(); return TRUE; } BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override { - if (s_pointSP >= 4) + if (s_cPoints >= 4) { OnEndDraw(FALSE); return TRUE; } - pushToPtStack(x, y); + pushToPoints(x, y); imageModel.NotifyImageChanged(); return TRUE; } void OnEndDraw(BOOL bCancel) override { - if (!bCancel && s_pointSP > 1) + if (!bCancel && s_cPoints > 1) { // FIXME: I couldn't calculate boundary rectangle from Bezier curve imageModel.PushImageForUndo(); @@ -1004,13 +1004,13 @@ struct ShapeTool : ToolBase void OnDrawOverlayOnImage(HDC hdc) { - if (s_pointSP <= 0) + if (s_cPoints <= 0) return; if (m_bLeftButton) - Poly(hdc, s_pointStack, (INT)s_pointSP, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE); + Poly(hdc, s_pPoints, (INT)s_cPoints, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE); else - Poly(hdc, s_pointStack, (INT)s_pointSP, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE); + Poly(hdc, s_pPoints, (INT)s_cPoints, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE); } void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override @@ -1018,31 +1018,31 @@ struct ShapeTool : ToolBase m_bLeftButton = bLeftButton; m_bClosed = FALSE; - if ((s_pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0)) - roundTo8Directions(s_pointStack[s_pointSP - 1].x, s_pointStack[s_pointSP - 1].y, x, y); + if ((s_cPoints > 0) && (GetAsyncKeyState(VK_SHIFT) < 0)) + roundTo8Directions(s_pPoints[s_cPoints - 1].x, s_pPoints[s_cPoints - 1].y, x, y); - pushToPtStack(x, y); + pushToPoints(x, y); - if (s_pointSP > 1 && bDoubleClick) + if (s_cPoints > 1 && bDoubleClick) { OnEndDraw(FALSE); return; } - if (s_pointSP == 1) - pushToPtStack(x, y); // We have to draw the first point + if (s_cPoints == 1) + pushToPoints(x, y); // We have to draw the first point imageModel.NotifyImageChanged(); } BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override { - if (s_pointSP > 1) + if (s_cPoints > 1) { if (GetAsyncKeyState(VK_SHIFT) < 0) - roundTo8Directions(s_pointStack[s_pointSP - 2].x, s_pointStack[s_pointSP - 2].y, x, y); + roundTo8Directions(s_pPoints[s_cPoints - 2].x, s_pPoints[s_cPoints - 2].y, x, y); - s_pointStack[s_pointSP - 1] = { x, y }; + s_pPoints[s_cPoints - 1] = { x, y }; } imageModel.NotifyImageChanged(); @@ -1051,27 +1051,27 @@ struct ShapeTool : ToolBase BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override { - if ((s_pointSP > 1) && (GetAsyncKeyState(VK_SHIFT) < 0)) - roundTo8Directions(s_pointStack[s_pointSP - 2].x, s_pointStack[s_pointSP - 2].y, x, y); + if ((s_cPoints > 1) && (GetAsyncKeyState(VK_SHIFT) < 0)) + roundTo8Directions(s_pPoints[s_cPoints - 2].x, s_pPoints[s_cPoints - 2].y, x, y); m_bClosed = FALSE; - if (nearlyEqualPoints(x, y, s_pointStack[0].x, s_pointStack[0].y)) + if (nearlyEqualPoints(x, y, s_pPoints[0].x, s_pPoints[0].y)) { OnEndDraw(FALSE); return TRUE; } - pushToPtStack(x, y); + pushToPoints(x, y); imageModel.NotifyImageChanged(); return TRUE; } void OnEndDraw(BOOL bCancel) override { - if (!bCancel && s_pointSP > 1) + if (!bCancel && s_cPoints > 1) { CRect rcPartial; - getBoundaryOfPtStack(rcPartial, s_pointSP, s_pointStack); + getBoundaryOfPoints(rcPartial, s_cPoints, s_pPoints); SIZE size = toolsModel.GetToolSize(); rcPartial.InflateRect((size.cx + 1) / 2, (size.cy + 1) / 2); diff --git a/base/applications/mspaint/toolsmodel.h b/base/applications/mspaint/toolsmodel.h index 2cd2e68d235..43d4c6ecf28 100644 --- a/base/applications/mspaint/toolsmodel.h +++ b/base/applications/mspaint/toolsmodel.h @@ -60,7 +60,6 @@ struct ToolBase void beginEvent(); void endEvent(); void reset(); - void pushToPtStack(LONG x, LONG y); static ToolBase* createToolObject(TOOLTYPE type); };
1 year, 1 month
1
0
0
0
[reactos] 01/01: [MSPAINT] mouse.cpp: Erase type warnings of SIZE_T vs. INT
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fd38a6f7887222465b771…
commit fd38a6f7887222465b771b8c31be6c208bdffe70 Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Sat Nov 25 14:07:46 2023 +0900 Commit: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> CommitDate: Sat Nov 25 14:09:20 2023 +0900 [MSPAINT] mouse.cpp: Erase type warnings of SIZE_T vs. INT CORE-19094 --- base/applications/mspaint/mouse.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp index 2f97ad9d079..af8fb48ab25 100644 --- a/base/applications/mspaint/mouse.cpp +++ b/base/applications/mspaint/mouse.cpp @@ -53,7 +53,7 @@ BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1) return (abs(x1 - x0) <= cxThreshold) && (abs(y1 - y0) <= cyThreshold); } -void getBoundaryOfPtStack(RECT& rcBoundary, INT cPoints, const POINT *pPoints) +void getBoundaryOfPtStack(RECT& rcBoundary, SIZE_T cPoints, const POINT *pPoints) { POINT ptMin = { MAXLONG, MAXLONG }, ptMax = { (LONG)MINLONG, (LONG)MINLONG }; while (cPoints-- > 0) @@ -94,7 +94,7 @@ void BuildMaskFromPtStack() ::FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH)); HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN)); HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH)); - ::Polygon(hdcMem, s_pointStack, s_pointSP); + ::Polygon(hdcMem, s_pointStack, (INT)s_pointSP); ::SelectObject(hdcMem, hbrOld); ::SelectObject(hdcMem, hPenOld); ::SelectObject(hdcMem, hbmOld); @@ -560,7 +560,7 @@ struct FreeSelTool : SelectionBaseTool if (!selectionModel.m_bShow && m_bDrawing) { /* Draw the freehand selection inverted/xored */ - Poly(hdc, s_pointStack, s_pointSP, 0, 0, 2, 0, FALSE, TRUE); + Poly(hdc, s_pointStack, (INT)s_pointSP, 0, 0, 2, 0, FALSE, TRUE); } } }; @@ -1008,9 +1008,9 @@ struct ShapeTool : ToolBase return; if (m_bLeftButton) - Poly(hdc, s_pointStack, s_pointSP, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE); + Poly(hdc, s_pointStack, (INT)s_pointSP, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE); else - Poly(hdc, s_pointStack, s_pointSP, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE); + Poly(hdc, s_pointStack, (INT)s_pointSP, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE); } void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
1 year, 1 month
1
0
0
0
[reactos] 01/01: [MSPAINT] Improve Undo/Redo handling of selection (#6035)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b8598e095d313bffd8169…
commit b8598e095d313bffd8169bd1ca8c1ee7b22026bd Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Sat Nov 25 13:44:31 2023 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Sat Nov 25 13:44:31 2023 +0900 [MSPAINT] Improve Undo/Redo handling of selection (#6035) Consistent behavior of the application. - Add ShiftPtStack and BuildMaskFromPtStack helper functions. - Move some codes of selectionModel to mouse.cpp. CORE-19226 --- base/applications/mspaint/canvas.cpp | 17 +--- base/applications/mspaint/canvas.h | 3 +- base/applications/mspaint/history.cpp | 20 ++--- base/applications/mspaint/history.h | 1 - base/applications/mspaint/main.cpp | 36 ++------ base/applications/mspaint/mouse.cpp | 128 +++++++++++++++++++-------- base/applications/mspaint/selectionmodel.cpp | 120 +++++-------------------- base/applications/mspaint/selectionmodel.h | 10 +-- base/applications/mspaint/toolsmodel.cpp | 3 + base/applications/mspaint/toolsmodel.h | 1 - 10 files changed, 134 insertions(+), 205 deletions(-) diff --git a/base/applications/mspaint/canvas.cpp b/base/applications/mspaint/canvas.cpp index fa6201cdf21..06074cf0c45 100644 --- a/base/applications/mspaint/canvas.cpp +++ b/base/applications/mspaint/canvas.cpp @@ -648,9 +648,9 @@ LRESULT CCanvasWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL LRESULT CCanvasWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - if (wParam == VK_ESCAPE && ::GetCapture() == m_hWnd) + if (wParam == VK_ESCAPE) { - cancelDrawing(); + OnEndDraw(TRUE); ::ReleaseCapture(); m_nMouseDownMsg = 0; m_hitCanvasSizeBox = HIT_NONE; @@ -698,19 +698,10 @@ LRESULT CCanvasWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH return 0; } -VOID CCanvasWindow::cancelDrawing() +VOID CCanvasWindow::OnEndDraw(BOOL bCancel) { - selectionModel.ClearColorImage(); - selectionModel.ClearMaskImage(); - m_drawing = FALSE; - toolsModel.OnEndDraw(TRUE); - Invalidate(FALSE); -} - -VOID CCanvasWindow::finishDrawing() -{ - toolsModel.OnEndDraw(FALSE); m_drawing = FALSE; + toolsModel.OnEndDraw(bCancel); Invalidate(FALSE); } diff --git a/base/applications/mspaint/canvas.h b/base/applications/mspaint/canvas.h index 5bdd1def467..ef0323df65f 100644 --- a/base/applications/mspaint/canvas.h +++ b/base/applications/mspaint/canvas.h @@ -42,8 +42,7 @@ public: BOOL m_drawing; - VOID cancelDrawing(); - VOID finishDrawing(); + VOID OnEndDraw(BOOL bCancel); VOID updateScrollRange(); VOID updateScrollPos(INT x = 0, INT y = 0); diff --git a/base/applications/mspaint/history.cpp b/base/applications/mspaint/history.cpp index 696e02656c2..c7b32cc5ab4 100644 --- a/base/applications/mspaint/history.cpp +++ b/base/applications/mspaint/history.cpp @@ -164,8 +164,13 @@ void ImageModel::PushImageForUndo(const RECT& rcPartial) part.m_bPartial = TRUE; part.m_rcPart = rcPartial; + CRect rcImage = { 0, 0, GetWidth(), GetHeight() }; + CRect& rc = part.m_rcPart; + if (!rc.IntersectRect(rc, rcImage)) + rc.SetRect(-1, -1, 0, 0); + HBITMAP hbmMaster = LockBitmap(); - part.m_hbmImage = getSubImage(hbmMaster, rcPartial); + part.m_hbmImage = getSubImage(hbmMaster, rc); UnlockBitmap(hbmMaster); PushDone(); @@ -351,16 +356,3 @@ void ImageModel::UnlockBitmap(HBITMAP hbmLocked) m_hbmMaster = hbmLocked; m_hbmOld = ::SelectObject(m_hDrawingDC, m_hbmMaster); // Re-select } - -void ImageModel::SelectionClone(BOOL bUndoable) -{ - if (!selectionModel.m_bShow || selectionModel.m_rc.IsRectEmpty()) - return; - - if (bUndoable) - PushImageForUndo(); - - selectionModel.DrawSelection(m_hDrawingDC, paletteModel.GetBgColor(), - toolsModel.IsBackgroundTransparent()); - NotifyImageChanged(); -} diff --git a/base/applications/mspaint/history.h b/base/applications/mspaint/history.h index 87c98515136..7dc949b31f4 100644 --- a/base/applications/mspaint/history.h +++ b/base/applications/mspaint/history.h @@ -51,7 +51,6 @@ public: void NotifyImageChanged(); BOOL IsBlackAndWhite(); void PushBlackAndWhite(); - void SelectionClone(BOOL bUndoable = TRUE); protected: HDC m_hDrawingDC; // The device context for this class diff --git a/base/applications/mspaint/main.cpp b/base/applications/mspaint/main.cpp index 7e3364678f1..c93a41a886a 100644 --- a/base/applications/mspaint/main.cpp +++ b/base/applications/mspaint/main.cpp @@ -406,7 +406,7 @@ void CMainWindow::alignChildrenToMainWindow() void CMainWindow::saveImage(BOOL overwrite) { - canvasWindow.finishDrawing(); + canvasWindow.OnEndDraw(FALSE); // Is the extension not supported? PWCHAR pchDotExt = PathFindExtensionW(g_szFileName); @@ -606,7 +606,7 @@ LRESULT CMainWindow::OnDestroy(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH BOOL CMainWindow::ConfirmSave() { - canvasWindow.finishDrawing(); + canvasWindow.OnEndDraw(FALSE); if (imageModel.IsImageSaved()) return TRUE; @@ -693,8 +693,6 @@ BOOL CMainWindow::CanUndo() const return (BOOL)textEditWindow.SendMessage(EM_CANUNDO); if (selectionModel.m_bShow && toolsModel.IsSelection()) return TRUE; - if (ToolBase::s_pointSP != 0) - return TRUE; return imageModel.CanUndo(); } @@ -702,8 +700,6 @@ BOOL CMainWindow::CanRedo() const { if (toolsModel.GetActiveTool() == TOOL_TEXT && ::IsWindowVisible(textEditWindow)) return FALSE; // There is no "WM_REDO" in EDIT control - if (ToolBase::s_pointSP != 0) - return TRUE; return imageModel.CanRedo(); } @@ -802,29 +798,11 @@ LRESULT CMainWindow::OnGetMinMaxInfo(UINT nMsg, WPARAM wParam, LPARAM lParam, BO LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - HWND hwndCapture; switch (wParam) { case VK_ESCAPE: - hwndCapture = GetCapture(); - if (hwndCapture) - { - if (canvasWindow.m_hWnd == hwndCapture || - fullscreenWindow.m_hWnd == hwndCapture) - { - ::SendMessageW(hwndCapture, nMsg, wParam, lParam); - } - } - else if (selectionModel.m_bShow) - { - selectionModel.HideSelection(); - } - else - { - canvasWindow.cancelDrawing(); - } + canvasWindow.PostMessage(nMsg, wParam, lParam); break; - case VK_LEFT: selectionModel.moveSelection(-1, 0); break; @@ -932,7 +910,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH GlobalFree(pd.hDevNames); break; case IDM_FILESEND: - canvasWindow.finishDrawing(); + canvasWindow.OnEndDraw(FALSE); if (!OpenMailer(m_hWnd, g_szFileName)) { ShowError(IDS_CANTSENDMAIL); @@ -963,7 +941,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH textEditWindow.PostMessage(WM_UNDO, 0, 0); break; } - canvasWindow.finishDrawing(); + canvasWindow.OnEndDraw(FALSE); imageModel.Undo(); break; case IDM_EDITREDO: @@ -972,7 +950,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH // There is no "WM_REDO" in EDIT control break; } - canvasWindow.finishDrawing(); + canvasWindow.OnEndDraw(FALSE); imageModel.Redo(); break; case IDM_EDITCOPY: @@ -1087,7 +1065,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH break; case TOOL_TEXT: - canvasWindow.cancelDrawing(); + canvasWindow.OnEndDraw(TRUE); break; default: break; diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp index 2dcec274e80..2f97ad9d079 100644 --- a/base/applications/mspaint/mouse.cpp +++ b/base/applications/mspaint/mouse.cpp @@ -9,9 +9,11 @@ #include "precomp.h" #include <atlalloc.h> -SIZE_T ToolBase::s_pointSP = 0; -static SIZE_T s_maxPointSP = 0; -static CHeapPtr<POINT, CLocalAllocator> s_pointStack; +static SIZE_T s_pointSP = 0; +static CHeapPtr<POINT, CLocalAllocator> s_pointsAllocated; +static POINT s_staticPointStack[512]; // 512 is enough +static SIZE_T s_maxPointSP = _countof(s_staticPointStack); +static LPPOINT s_pointStack = s_staticPointStack; static POINT g_ptStart, g_ptEnd; /* FUNCTIONS ********************************************************/ @@ -69,13 +71,50 @@ void getBoundaryOfPtStack(RECT& rcBoundary, INT cPoints, const POINT *pPoints) rcBoundary = rc; } +void ShiftPtStack(INT dx, INT dy) +{ + for (SIZE_T i = 0; i < s_pointSP; ++i) + { + POINT& pt = s_pointStack[i]; + pt.x += dx; + pt.y += dy; + } +} + +void BuildMaskFromPtStack() +{ + CRect rc; + getBoundaryOfPtStack(rc, s_pointSP, s_pointStack); + + ShiftPtStack(-rc.left, -rc.top); + + HDC hdcMem = ::CreateCompatibleDC(NULL); + HBITMAP hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL); + HGDIOBJ hbmOld = ::SelectObject(hdcMem, hbmMask); + ::FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH)); + HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN)); + HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH)); + ::Polygon(hdcMem, s_pointStack, s_pointSP); + ::SelectObject(hdcMem, hbrOld); + ::SelectObject(hdcMem, hPenOld); + ::SelectObject(hdcMem, hbmOld); + ::DeleteDC(hdcMem); + + selectionModel.setMask(rc, hbmMask); +} + void ToolBase::reset() { + if (s_pointStack != s_staticPointStack) + { + s_pointsAllocated.Free(); + s_pointStack = s_staticPointStack; + s_maxPointSP = _countof(s_staticPointStack); + } + s_pointSP = 0; g_ptEnd = g_ptStart = { -1, -1 }; - selectionModel.ResetPtStack(); - if (selectionModel.m_bShow) { selectionModel.Landing(); @@ -103,16 +142,20 @@ void ToolBase::endEvent() void ToolBase::pushToPtStack(LONG x, LONG y) { - if (s_pointSP >= s_maxPointSP) + if (s_pointSP + 1 >= s_maxPointSP) { SIZE_T newMax = s_maxPointSP + 512; SIZE_T cbNew = newMax * sizeof(POINT); - if (!s_pointStack.ReallocateBytes(cbNew)) + if (!s_pointsAllocated.ReallocateBytes(cbNew)) { ATLTRACE("%d, %d, %d\n", (INT)s_pointSP, (INT)s_maxPointSP, (INT)cbNew); return; } + if (s_pointStack == s_staticPointStack) + CopyMemory(s_pointsAllocated, s_staticPointStack, s_pointSP * sizeof(POINT)); + + s_pointStack = s_pointsAllocated; s_maxPointSP = newMax; } @@ -327,12 +370,13 @@ struct SmoothDrawTool : ToolBase } }; -struct SelectionBaseTool : SmoothDrawTool +struct SelectionBaseTool : ToolBase { BOOL m_bLeftButton = FALSE; BOOL m_bCtrlKey = FALSE; BOOL m_bShiftKey = FALSE; BOOL m_bDrawing = FALSE; + BOOL m_bNoDrawBack = FALSE; HITTEST m_hitSelection = HIT_NONE; BOOL isRectSelect() const @@ -342,13 +386,19 @@ struct SelectionBaseTool : SmoothDrawTool void OnDrawOverlayOnImage(HDC hdc) override { - if (!selectionModel.IsLanded()) - selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); + if (selectionModel.IsLanded() || !selectionModel.m_bShow) + return; + + if (!m_bNoDrawBack) + selectionModel.DrawBackground(hdc, selectionModel.m_rgbBack); + + selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); } void OnDrawOverlayOnCanvas(HDC hdc) override { - selectionModel.drawFrameOnCanvas(hdc); + if (m_bDrawing || selectionModel.m_bShow) + selectionModel.drawFrameOnCanvas(hdc); } void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override @@ -374,12 +424,14 @@ struct SelectionBaseTool : SmoothDrawTool if (hit != HIT_NONE) // Dragging of selection started? { if (m_bCtrlKey || m_bShiftKey) - imageModel.SelectionClone(); - + { + imageModel.PushImageForUndo(); + toolsModel.OnDrawOverlayOnImage(imageModel.GetDC()); + } m_hitSelection = hit; selectionModel.m_ptHit = pt; selectionModel.TakeOff(); - + m_bNoDrawBack |= (m_bCtrlKey || m_bShiftKey); imageModel.NotifyImageChanged(); return; } @@ -394,8 +446,8 @@ struct SelectionBaseTool : SmoothDrawTool } else { - selectionModel.ResetPtStack(); - selectionModel.PushToPtStack(pt); + s_pointSP = 0; + pushToPtStack(pt.x, pt.y); } imageModel.NotifyImageChanged(); @@ -411,18 +463,22 @@ struct SelectionBaseTool : SmoothDrawTool if (m_hitSelection != HIT_NONE) // Now dragging selection? { if (m_bShiftKey) - imageModel.SelectionClone(m_bShiftKey); + toolsModel.OnDrawOverlayOnImage(imageModel.GetDC()); selectionModel.Dragging(m_hitSelection, pt); imageModel.NotifyImageChanged(); return TRUE; } + if (isRectSelect() && ::GetKeyState(VK_SHIFT) < 0) + regularize(g_ptStart.x, g_ptStart.y, pt.x, pt.y); + imageModel.Clamp(pt); + if (isRectSelect()) selectionModel.SetRectFromPoints(g_ptStart, pt); else - selectionModel.PushToPtStack(pt); + pushToPtStack(pt.x, pt.y); imageModel.NotifyImageChanged(); return TRUE; @@ -438,13 +494,20 @@ struct SelectionBaseTool : SmoothDrawTool if (m_hitSelection != HIT_NONE) // Dragging of selection ended? { + if (m_bShiftKey) + toolsModel.OnDrawOverlayOnImage(imageModel.GetDC()); + selectionModel.Dragging(m_hitSelection, pt); m_hitSelection = HIT_NONE; imageModel.NotifyImageChanged(); return TRUE; } + if (isRectSelect() && ::GetKeyState(VK_SHIFT) < 0) + regularize(g_ptStart.x, g_ptStart.y, pt.x, pt.y); + imageModel.Clamp(pt); + if (isRectSelect()) { selectionModel.SetRectFromPoints(g_ptStart, pt); @@ -452,18 +515,19 @@ struct SelectionBaseTool : SmoothDrawTool } else { - if (selectionModel.PtStackSize() > 2) + if (s_pointSP > 2) { - selectionModel.BuildMaskFromPtStack(); + BuildMaskFromPtStack(); selectionModel.m_bShow = TRUE; } else { - selectionModel.ResetPtStack(); + s_pointSP = 0; selectionModel.m_bShow = FALSE; } } + m_bNoDrawBack = FALSE; imageModel.NotifyImageChanged(); return TRUE; } @@ -475,6 +539,7 @@ struct SelectionBaseTool : SmoothDrawTool else selectionModel.Landing(); + m_bDrawing = FALSE; m_hitSelection = HIT_NONE; ToolBase::OnEndDraw(bCancel); } @@ -488,34 +553,21 @@ struct SelectionBaseTool : SmoothDrawTool // TOOL_FREESEL struct FreeSelTool : SelectionBaseTool { - void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override - { - if (m_bShiftKey && !m_bCtrlKey) - { - // TODO: - } - } - void OnDrawOverlayOnImage(HDC hdc) override { SelectionBaseTool::OnDrawOverlayOnImage(hdc); if (!selectionModel.m_bShow && m_bDrawing) - selectionModel.DrawFramePoly(hdc); + { + /* Draw the freehand selection inverted/xored */ + Poly(hdc, s_pointStack, s_pointSP, 0, 0, 2, 0, FALSE, TRUE); + } } }; // TOOL_RECTSEL struct RectSelTool : SelectionBaseTool { - void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override - { - if (m_bShiftKey && !m_bCtrlKey) - { - // TODO: - } - } - void OnDrawOverlayOnImage(HDC hdc) override { SelectionBaseTool::OnDrawOverlayOnImage(hdc); diff --git a/base/applications/mspaint/selectionmodel.cpp b/base/applications/mspaint/selectionmodel.cpp index ee18b521188..2699a8517e9 100644 --- a/base/applications/mspaint/selectionmodel.cpp +++ b/base/applications/mspaint/selectionmodel.cpp @@ -15,8 +15,6 @@ SelectionModel selectionModel; SelectionModel::SelectionModel() : m_hbmColor(NULL) , m_hbmMask(NULL) - , m_ptStack(NULL) - , m_iPtSP(0) , m_rgbBack(RGB(255, 255, 255)) , m_bShow(FALSE) , m_bContentChanged(FALSE) @@ -30,69 +28,6 @@ SelectionModel::~SelectionModel() { ClearColorImage(); ClearMaskImage(); - ResetPtStack(); -} - -void SelectionModel::ResetPtStack() -{ - if (m_ptStack) - { - free(m_ptStack); - m_ptStack = NULL; - } - m_iPtSP = 0; -} - -void SelectionModel::PushToPtStack(POINT pt) -{ -#define GROW_COUNT 256 - if (m_iPtSP % GROW_COUNT == 0) - { - INT nNewCount = m_iPtSP + GROW_COUNT; - LPPOINT pptNew = (LPPOINT)realloc(m_ptStack, sizeof(POINT) * nNewCount); - if (pptNew == NULL) - return; - m_ptStack = pptNew; - } - m_ptStack[m_iPtSP] = pt; - m_iPtSP++; -#undef GROW_COUNT -} - -void SelectionModel::ShiftPtStack(INT dx, INT dy) -{ - for (INT i = 0; i < m_iPtSP; ++i) - { - POINT& pt = m_ptStack[i]; - pt.x += dx; - pt.y += dy; - } -} - -void SelectionModel::BuildMaskFromPtStack() -{ - CRect rc; - getBoundaryOfPtStack(rc, m_iPtSP, m_ptStack); - - m_rc = m_rcOld = rc; - - ClearMaskImage(); - - ShiftPtStack(-m_rcOld.left, -m_rcOld.top); - - HDC hdcMem = ::CreateCompatibleDC(NULL); - m_hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL); - HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_hbmMask); - ::FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH)); - HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN)); - HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH)); - ::Polygon(hdcMem, m_ptStack, m_iPtSP); - ::SelectObject(hdcMem, hbrOld); - ::SelectObject(hdcMem, hPenOld); - ::SelectObject(hdcMem, hbmOld); - ::DeleteDC(hdcMem); - - ShiftPtStack(+m_rcOld.left, +m_rcOld.top); } void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg) @@ -100,11 +35,11 @@ void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg) if (m_rcOld.IsRectEmpty()) return; - HGDIOBJ hPenOld = ::SelectObject(hDCImage, ::GetStockObject(NULL_PEN)); - HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::CreateSolidBrush(crBg)); - ::Polygon(hDCImage, m_ptStack, m_iPtSP); - ::DeleteObject(::SelectObject(hDCImage, hbrOld)); - ::SelectObject(hDCImage, hPenOld); + HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::GetStockObject(DC_BRUSH)); + ::SetDCBrushColor(hDCImage, crBg); + ::MaskBlt(hDCImage, m_rcOld.left, m_rcOld.top, m_rcOld.Width(), m_rcOld.Height(), + hDCImage, m_rcOld.left, m_rcOld.top, m_hbmMask, 0, 0, MAKEROP4(PATCOPY, SRCCOPY)); + ::SelectObject(hDCImage, hbrOld); } void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg) @@ -115,12 +50,12 @@ void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg) Rect(hDCImage, m_rcOld.left, m_rcOld.top, m_rcOld.right, m_rcOld.bottom, crBg, crBg, 0, 1); } -void SelectionModel::DrawBackground(HDC hDCImage) +void SelectionModel::DrawBackground(HDC hDCImage, COLORREF crBg) { if (toolsModel.GetActiveTool() == TOOL_FREESEL) - DrawBackgroundPoly(hDCImage, paletteModel.GetBgColor()); + DrawBackgroundPoly(hDCImage, crBg); else - DrawBackgroundRect(hDCImage, paletteModel.GetBgColor()); + DrawBackgroundRect(hDCImage, crBg); } void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent) @@ -143,6 +78,15 @@ void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTranspar DeleteDC(hMemDC); } +void SelectionModel::setMask(const CRect& rc, HBITMAP hbmMask) +{ + if (m_hbmMask) + ::DeleteObject(m_hbmMask); + + m_hbmMask = hbmMask; + m_rc = m_rcOld = rc; +} + HBITMAP SelectionModel::GetSelectionContents() { if (m_hbmColor) @@ -178,17 +122,6 @@ BOOL SelectionModel::TakeOff() // Save the selection area m_rcOld = m_rc; - if (toolsModel.GetActiveTool() == TOOL_RECTSEL) - { - imageModel.PushImageForUndo(); - selectionModel.DrawBackgroundRect(imageModel.GetDC(), selectionModel.m_rgbBack); - } - else if (toolsModel.GetActiveTool() == TOOL_FREESEL) - { - imageModel.PushImageForUndo(); - selectionModel.DrawBackgroundPoly(imageModel.GetDC(), selectionModel.m_rgbBack); - } - imageModel.NotifyImageChanged(); return TRUE; } @@ -201,12 +134,12 @@ void SelectionModel::Landing() return; } - m_bShow = FALSE; - if (m_bContentChanged || (!m_rc.EqualRect(m_rcOld) && !m_rc.IsRectEmpty() && !m_rcOld.IsRectEmpty())) { - imageModel.PushImageForUndo(); + CRect rc; + rc.UnionRect(m_rc, m_rcOld); + imageModel.PushImageForUndo(rc); canvasWindow.m_drawing = FALSE; toolsModel.OnDrawOverlayOnImage(imageModel.GetDC()); @@ -397,17 +330,6 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int NotifyContentChanged(); } -int SelectionModel::PtStackSize() const -{ - return m_iPtSP; -} - -void SelectionModel::DrawFramePoly(HDC hDCImage) -{ - /* draw the freehand selection inverted/xored */ - Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE); -} - void SelectionModel::SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo) { m_rc = CRect(ptFrom, ptTo); @@ -491,7 +413,7 @@ void SelectionModel::DeleteSelection() TakeOff(); imageModel.PushImageForUndo(); - DrawBackground(imageModel.GetDC()); + DrawBackground(imageModel.GetDC(), paletteModel.GetBgColor()); HideSelection(); } diff --git a/base/applications/mspaint/selectionmodel.h b/base/applications/mspaint/selectionmodel.h index e83786191ff..d9007d6df00 100644 --- a/base/applications/mspaint/selectionmodel.h +++ b/base/applications/mspaint/selectionmodel.h @@ -13,8 +13,6 @@ class SelectionModel private: HBITMAP m_hbmColor; HBITMAP m_hbmMask; - POINT *m_ptStack; - int m_iPtSP; public: COLORREF m_rgbBack; @@ -27,11 +25,8 @@ public: SelectionModel(); ~SelectionModel(); - void ResetPtStack(); - void PushToPtStack(POINT pt); - int PtStackSize() const; void SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo); - void BuildMaskFromPtStack(); + void setMask(const CRect& rc, HBITMAP hbmMask); BOOL TakeOff(); void Landing(); @@ -43,8 +38,7 @@ public: void moveSelection(INT xDelta, INT yDelta); HBITMAP GetSelectionContents(); - void DrawFramePoly(HDC hDCImage); - void DrawBackground(HDC hDCImage); + void DrawBackground(HDC hDCImage, COLORREF crBg); void DrawBackgroundPoly(HDC hDCImage, COLORREF crBg); void DrawBackgroundRect(HDC hDCImage, COLORREF crBg); void DrawSelection(HDC hDCImage, COLORREF crBg = 0, BOOL bBgTransparent = FALSE); diff --git a/base/applications/mspaint/toolsmodel.cpp b/base/applications/mspaint/toolsmodel.cpp index c19a1152c24..f789fbf9d6a 100644 --- a/base/applications/mspaint/toolsmodel.cpp +++ b/base/applications/mspaint/toolsmodel.cpp @@ -209,6 +209,9 @@ SIZE ToolsModel::GetToolSize() const { case TOOL_FREESEL: case TOOL_RECTSEL: + size.cx = selectionModel.m_rc.Width(); + size.cy = selectionModel.m_rc.Height(); + break; case TOOL_COLOR: case TOOL_ZOOM: case TOOL_TEXT: diff --git a/base/applications/mspaint/toolsmodel.h b/base/applications/mspaint/toolsmodel.h index 668c7820bb3..2cd2e68d235 100644 --- a/base/applications/mspaint/toolsmodel.h +++ b/base/applications/mspaint/toolsmodel.h @@ -42,7 +42,6 @@ struct ToolBase { HDC m_hdc; COLORREF m_fg, m_bg; - static SIZE_T s_pointSP; ToolBase() : m_hdc(NULL) { } virtual ~ToolBase() { }
1 year, 1 month
1
0
0
0
[reactos] 01/01: [SETUPAPI] cfgmgr.c: Minor debug strings fix
by Thamatip Chitpong
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ab0119c61f74a1c0e59d9…
commit ab0119c61f74a1c0e59d94db2054faec38a31083 Author: Thamatip Chitpong <thamatip.chitpong(a)reactos.org> AuthorDate: Sat Nov 25 07:50:23 2023 +0700 Commit: GitHub <noreply(a)github.com> CommitDate: Sat Nov 25 07:50:23 2023 +0700 [SETUPAPI] cfgmgr.c: Minor debug strings fix --- dll/win32/setupapi/cfgmgr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dll/win32/setupapi/cfgmgr.c b/dll/win32/setupapi/cfgmgr.c index 929e35cc14d..7fd00b122e8 100644 --- a/dll/win32/setupapi/cfgmgr.c +++ b/dll/win32/setupapi/cfgmgr.c @@ -6235,7 +6235,7 @@ CM_Open_Class_KeyW( _Out_ PHKEY phkClass, _In_ ULONG ulFlags) { - TRACE("CM_Open_Class_KeyW%p %s %lx %lx %p %lx)\n", + TRACE("CM_Open_Class_KeyW(%p %s %lx %lx %p %lx)\n", debugstr_guid(pClassGuid), debugstr_w(pszClassName), samDesired, Disposition, phkClass, ulFlags); @@ -6566,7 +6566,7 @@ CM_Query_And_Remove_SubTreeA( _In_ ULONG ulNameLength, _In_ ULONG ulFlags) { - TRACE("CM_Query_And_Remove_SubTreeA(%lx %p %s %lu %lx)\n", + TRACE("CM_Query_And_Remove_SubTreeA(%lx %p %p %lu %lx)\n", dnAncestor, pVetoType, pszVetoName, ulNameLength, ulFlags); return CM_Query_And_Remove_SubTree_ExA(dnAncestor, pVetoType, pszVetoName,
1 year, 1 month
1
0
0
0
[reactos] 01/01: [IMM32][SDK] Implement IME Soft Keyboard Type T1 (#6021)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bd0629905963e0002ef77…
commit bd0629905963e0002ef778cd3b26ebcd95185dbb Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Fri Nov 24 23:02:19 2023 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Fri Nov 24 23:02:19 2023 +0900 [IMM32][SDK] Implement IME Soft Keyboard Type T1 (#6021) - Rename version.rc as imm32.rc. - Add resource.h and t1keys.h. - Add some resource bitmaps. - Modify <immdev.h>. Test: Press Ctrl+Alt+comma on FreeCJ2004. NOTE: There's a visual bug in PatBlt with negative values. CORE-19268 --- dll/win32/imm32/CMakeLists.txt | 23 +- dll/win32/imm32/{version.rc => imm32.rc} | 26 + dll/win32/imm32/res/1033_Bitmap_100.bmp | Bin 0 -> 190 bytes dll/win32/imm32/res/1033_Bitmap_101.bmp | Bin 0 -> 190 bytes dll/win32/imm32/res/1033_Bitmap_102.bmp | Bin 0 -> 226 bytes dll/win32/imm32/res/1033_Bitmap_103.bmp | Bin 0 -> 262 bytes dll/win32/imm32/res/1033_Bitmap_104.bmp | Bin 0 -> 226 bytes dll/win32/imm32/res/1033_Bitmap_105.bmp | Bin 0 -> 190 bytes dll/win32/imm32/res/1033_Bitmap_106.bmp | Bin 0 -> 226 bytes dll/win32/imm32/res/1033_Bitmap_107.bmp | Bin 0 -> 190 bytes dll/win32/imm32/res/1033_Bitmap_108.bmp | Bin 0 -> 446 bytes dll/win32/imm32/res/2052_Bitmap_201.bmp | Bin 0 -> 502 bytes dll/win32/imm32/res/2052_Bitmap_202.bmp | Bin 0 -> 502 bytes dll/win32/imm32/res/2052_Bitmap_203.bmp | Bin 0 -> 598 bytes dll/win32/imm32/res/2052_Bitmap_204.bmp | Bin 0 -> 598 bytes dll/win32/imm32/res/2052_Bitmap_205.bmp | Bin 0 -> 790 bytes dll/win32/imm32/res/2052_Bitmap_206.bmp | Bin 0 -> 518 bytes dll/win32/imm32/res/2052_Bitmap_207.bmp | Bin 0 -> 518 bytes dll/win32/imm32/res/2052_Bitmap_208.bmp | Bin 0 -> 518 bytes dll/win32/imm32/res/2052_Bitmap_209.bmp | Bin 0 -> 446 bytes dll/win32/imm32/resource.h | 19 + dll/win32/imm32/softkbd.c | 1260 +++++++++++++++++++++++++++--- dll/win32/imm32/t1keys.h | 68 ++ sdk/include/ddk/immdev.h | 16 +- 24 files changed, 1295 insertions(+), 117 deletions(-) diff --git a/dll/win32/imm32/CMakeLists.txt b/dll/win32/imm32/CMakeLists.txt index d5b2ea12af4..b765ec172ab 100644 --- a/dll/win32/imm32/CMakeLists.txt +++ b/dll/win32/imm32/CMakeLists.txt @@ -22,8 +22,29 @@ list(APPEND SOURCE ${CMAKE_CURRENT_BINARY_DIR}/imm32_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/imm32.def) -add_library(imm32 MODULE ${SOURCE} version.rc) +list(APPEND imm32_rc_deps + ${CMAKE_CURRENT_SOURCE_DIR}/res/1033_Bitmap_100.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/1033_Bitmap_101.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/1033_Bitmap_102.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/1033_Bitmap_103.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/1033_Bitmap_104.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/1033_Bitmap_105.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/1033_Bitmap_106.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/1033_Bitmap_107.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/1033_Bitmap_108.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/2052_Bitmap_201.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/2052_Bitmap_202.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/2052_Bitmap_203.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/2052_Bitmap_204.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/2052_Bitmap_205.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/2052_Bitmap_206.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/2052_Bitmap_207.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/2052_Bitmap_208.bmp + ${CMAKE_CURRENT_SOURCE_DIR}/res/2052_Bitmap_209.bmp) + +add_library(imm32 MODULE ${SOURCE} imm32.rc) set_module_type(imm32 win32dll UNICODE ENTRYPOINT ImmDllInitialize 12) +set_source_files_properties(imm32.rc PROPERTIES OBJECT_DEPENDS "${imm32_rc_deps}") target_link_libraries(imm32 wine win32ksys) add_importlibs(imm32 advapi32 user32 gdi32 kernel32 ntdll) add_cd_file(TARGET imm32 DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/imm32/version.rc b/dll/win32/imm32/imm32.rc similarity index 51% rename from dll/win32/imm32/version.rc rename to dll/win32/imm32/imm32.rc index ae821025c01..317f986b7f2 100644 --- a/dll/win32/imm32/version.rc +++ b/dll/win32/imm32/imm32.rc @@ -24,3 +24,29 @@ #define WINE_PRODUCTVERSION_STR "5.1.2600.2180" #include "wine/wine_common_ver.rc" + +#include "resource.h" + +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL + +IDB_T1_BACKSPACE BITMAP "res/1033_Bitmap_100.bmp" +IDB_T1_TAB BITMAP "res/1033_Bitmap_101.bmp" +IDB_T1_CAPS BITMAP "res/1033_Bitmap_102.bmp" +IDB_T1_ENTER BITMAP "res/1033_Bitmap_103.bmp" +IDB_T1_SHIFT BITMAP "res/1033_Bitmap_104.bmp" +IDB_T1_CTRL BITMAP "res/1033_Bitmap_105.bmp" +IDB_T1_ESCAPE BITMAP "res/1033_Bitmap_106.bmp" +IDB_T1_ALT BITMAP "res/1033_Bitmap_107.bmp" +IDB_T1_CHARS BITMAP "res/1033_Bitmap_108.bmp" + +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED + +IDB_C1_BACKSPACE BITMAP "res/2052_Bitmap_201.bmp" +IDB_C1_TAB BITMAP "res/2052_Bitmap_202.bmp" +IDB_C1_CAPS BITMAP "res/2052_Bitmap_203.bmp" +IDB_C1_ENTER BITMAP "res/2052_Bitmap_204.bmp" +IDB_C1_SHIFT BITMAP "res/2052_Bitmap_205.bmp" +IDB_C1_INS BITMAP "res/2052_Bitmap_206.bmp" +IDB_C1_DEL BITMAP "res/2052_Bitmap_207.bmp" +IDB_C1_ESCAPE BITMAP "res/2052_Bitmap_208.bmp" +IDB_C1_CHARS BITMAP "res/2052_Bitmap_209.bmp" diff --git a/dll/win32/imm32/res/1033_Bitmap_100.bmp b/dll/win32/imm32/res/1033_Bitmap_100.bmp new file mode 100644 index 00000000000..79684fd689d Binary files /dev/null and b/dll/win32/imm32/res/1033_Bitmap_100.bmp differ diff --git a/dll/win32/imm32/res/1033_Bitmap_101.bmp b/dll/win32/imm32/res/1033_Bitmap_101.bmp new file mode 100644 index 00000000000..25cbf71f15c Binary files /dev/null and b/dll/win32/imm32/res/1033_Bitmap_101.bmp differ diff --git a/dll/win32/imm32/res/1033_Bitmap_102.bmp b/dll/win32/imm32/res/1033_Bitmap_102.bmp new file mode 100644 index 00000000000..063dbf4361b Binary files /dev/null and b/dll/win32/imm32/res/1033_Bitmap_102.bmp differ diff --git a/dll/win32/imm32/res/1033_Bitmap_103.bmp b/dll/win32/imm32/res/1033_Bitmap_103.bmp new file mode 100644 index 00000000000..44fdf073c2f Binary files /dev/null and b/dll/win32/imm32/res/1033_Bitmap_103.bmp differ diff --git a/dll/win32/imm32/res/1033_Bitmap_104.bmp b/dll/win32/imm32/res/1033_Bitmap_104.bmp new file mode 100644 index 00000000000..384b6cae779 Binary files /dev/null and b/dll/win32/imm32/res/1033_Bitmap_104.bmp differ diff --git a/dll/win32/imm32/res/1033_Bitmap_105.bmp b/dll/win32/imm32/res/1033_Bitmap_105.bmp new file mode 100644 index 00000000000..49dc2b9bc84 Binary files /dev/null and b/dll/win32/imm32/res/1033_Bitmap_105.bmp differ diff --git a/dll/win32/imm32/res/1033_Bitmap_106.bmp b/dll/win32/imm32/res/1033_Bitmap_106.bmp new file mode 100644 index 00000000000..01890744f87 Binary files /dev/null and b/dll/win32/imm32/res/1033_Bitmap_106.bmp differ diff --git a/dll/win32/imm32/res/1033_Bitmap_107.bmp b/dll/win32/imm32/res/1033_Bitmap_107.bmp new file mode 100644 index 00000000000..755312a30fc Binary files /dev/null and b/dll/win32/imm32/res/1033_Bitmap_107.bmp differ diff --git a/dll/win32/imm32/res/1033_Bitmap_108.bmp b/dll/win32/imm32/res/1033_Bitmap_108.bmp new file mode 100644 index 00000000000..d98a6107674 Binary files /dev/null and b/dll/win32/imm32/res/1033_Bitmap_108.bmp differ diff --git a/dll/win32/imm32/res/2052_Bitmap_201.bmp b/dll/win32/imm32/res/2052_Bitmap_201.bmp new file mode 100644 index 00000000000..d38078fa5bd Binary files /dev/null and b/dll/win32/imm32/res/2052_Bitmap_201.bmp differ diff --git a/dll/win32/imm32/res/2052_Bitmap_202.bmp b/dll/win32/imm32/res/2052_Bitmap_202.bmp new file mode 100644 index 00000000000..ea86471d6f4 Binary files /dev/null and b/dll/win32/imm32/res/2052_Bitmap_202.bmp differ diff --git a/dll/win32/imm32/res/2052_Bitmap_203.bmp b/dll/win32/imm32/res/2052_Bitmap_203.bmp new file mode 100644 index 00000000000..d2def3fe5a7 Binary files /dev/null and b/dll/win32/imm32/res/2052_Bitmap_203.bmp differ diff --git a/dll/win32/imm32/res/2052_Bitmap_204.bmp b/dll/win32/imm32/res/2052_Bitmap_204.bmp new file mode 100644 index 00000000000..b40316891af Binary files /dev/null and b/dll/win32/imm32/res/2052_Bitmap_204.bmp differ diff --git a/dll/win32/imm32/res/2052_Bitmap_205.bmp b/dll/win32/imm32/res/2052_Bitmap_205.bmp new file mode 100644 index 00000000000..6a3e43bea2e Binary files /dev/null and b/dll/win32/imm32/res/2052_Bitmap_205.bmp differ diff --git a/dll/win32/imm32/res/2052_Bitmap_206.bmp b/dll/win32/imm32/res/2052_Bitmap_206.bmp new file mode 100644 index 00000000000..f86ae147591 Binary files /dev/null and b/dll/win32/imm32/res/2052_Bitmap_206.bmp differ diff --git a/dll/win32/imm32/res/2052_Bitmap_207.bmp b/dll/win32/imm32/res/2052_Bitmap_207.bmp new file mode 100644 index 00000000000..baa4c76d272 Binary files /dev/null and b/dll/win32/imm32/res/2052_Bitmap_207.bmp differ diff --git a/dll/win32/imm32/res/2052_Bitmap_208.bmp b/dll/win32/imm32/res/2052_Bitmap_208.bmp new file mode 100644 index 00000000000..e29b9c40973 Binary files /dev/null and b/dll/win32/imm32/res/2052_Bitmap_208.bmp differ diff --git a/dll/win32/imm32/res/2052_Bitmap_209.bmp b/dll/win32/imm32/res/2052_Bitmap_209.bmp new file mode 100644 index 00000000000..485074a9469 Binary files /dev/null and b/dll/win32/imm32/res/2052_Bitmap_209.bmp differ diff --git a/dll/win32/imm32/resource.h b/dll/win32/imm32/resource.h new file mode 100644 index 00000000000..9dba6404099 --- /dev/null +++ b/dll/win32/imm32/resource.h @@ -0,0 +1,19 @@ +/* Bitmap IDs */ +#define IDB_T1_BACKSPACE 100 +#define IDB_T1_TAB 101 +#define IDB_T1_CAPS 102 +#define IDB_T1_ENTER 103 +#define IDB_T1_SHIFT 104 +#define IDB_T1_CTRL 105 +#define IDB_T1_ESCAPE 106 +#define IDB_T1_ALT 107 +#define IDB_T1_CHARS 108 +#define IDB_C1_BACKSPACE 201 +#define IDB_C1_TAB 202 +#define IDB_C1_CAPS 203 +#define IDB_C1_ENTER 204 +#define IDB_C1_SHIFT 205 +#define IDB_C1_INS 206 +#define IDB_C1_DEL 207 +#define IDB_C1_ESCAPE 208 +#define IDB_C1_CHARS 209 diff --git a/dll/win32/imm32/softkbd.c b/dll/win32/imm32/softkbd.c index 551331ffe40..8cf17248760 100644 --- a/dll/win32/imm32/softkbd.c +++ b/dll/win32/imm32/softkbd.c @@ -1,22 +1,53 @@ /* * PROJECT: ReactOS IMM32 * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later
) - * PURPOSE: Implementing IMM Software Keyboard + * PURPOSE: Implementing IME Soft Keyboard * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> */ #include "precomp.h" +#include "resource.h" WINE_DEFAULT_DEBUG_CHANNEL(imm); -static UINT s_uScanCode[256]; -static RECT s_rcWorkArea; -static POINT s_ptRaiseEdge; -static LOGFONTW s_lfSKT1Font; -static BOOL s_bWannaInitSoftKBD = TRUE; +/* + * There are two types of IME Soft Keyboard: Type T1 and Type C1. + * T1 is created for Traditional Chinese but not limitted to it. + * C1 is created for Simplified Chinese but not limitted to it. + * Type C1 has SHIFT status while Type T1 hasn't. + */ + +static UINT guScanCode[256]; /* Mapping: virtual key --> scan code */ +static POINT gptRaiseEdge; /* Border + Edge metrics */ +static BOOL g_bWantSoftKBDMetrics = TRUE; + +static inline BOOL +Imm32PtInRect( + _In_ const POINT *ppt, + _In_ LONG x, + _In_ LONG y, + _In_ LONG cx, + _In_ LONG cy) +{ + return (x <= ppt->x) && (ppt->x < x + cx) && (y <= ppt->y) && (ppt->y < y + cy); +} + +static inline INT +Imm32Clamp( + _In_ INT x, + _In_ INT xMin, + _In_ INT xMax) +{ + if (x < xMin) + return xMin; + if (x > xMax) + return xMax; + return x; +} static VOID -Imm32GetAllMonitorSize(_Out_ LPRECT prcWork) +Imm32GetAllMonitorSize( + _Out_ LPRECT prcWork) { if (GetSystemMetrics(SM_CMONITORS) == 1) { @@ -31,8 +62,8 @@ Imm32GetAllMonitorSize(_Out_ LPRECT prcWork) } static BOOL -Imm32GetNearestMonitorSize( - _In_ HWND hwnd, +Imm32GetNearestWorkArea( + _In_opt_ HWND hwnd, _Out_ LPRECT prcWork) { HMONITOR hMonitor; @@ -46,39 +77,1054 @@ Imm32GetNearestMonitorSize( hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (!hMonitor) + { + ERR("hwnd: %p\n", hwnd); return FALSE; + } ZeroMemory(&mi, sizeof(mi)); mi.cbSize = sizeof(mi); GetMonitorInfoW(hMonitor, &mi); - *prcWork = mi.rcWork; return TRUE; } -/* Software keyboard window procedure (Traditional Chinese) */ +/***************************************************************************** + * IME Soft Keyboard Type T1 + */ + +#define T1_CLASSNAMEW L"SoftKBDClsT1" + +#undef DEFINE_T1K +#define DEFINE_T1K(t1k_code, virtual_key_code, t1k_code_name, virtual_key_name, is_special) \ + t1k_code_name = t1k_code, + +/* Define T1 internal codes (T1K_...) */ +typedef enum T1KEY +{ +#include "t1keys.h" +} T1KEY; + +#undef DEFINE_T1K +#define DEFINE_T1K(t1k_code, virtual_key_code, t1k_code_name, virtual_key_name, is_special) \ + virtual_key_code, + +#define T1K_MAX 60 + +/* Mapping: T1K --> Virtual Key */ +const BYTE gT1K2VK[T1K_MAX] = +{ +#include "t1keys.h" +}; + +typedef struct T1WINDOW +{ + INT cxDefWidth; /* Regular key width */ + INT cxWidth47; /* [BackSpace] width */ + INT cxWidth48; /* [Tab] width */ + INT cxWidth49; /* [Caps] width */ + INT cxWidth50; /* [Enter] width */ + INT cxWidth51or52; /* [Shift] width */ + INT cxWidth53or54; /* [Ctrl] width */ + INT cxWidth55or56; /* [Alt] width */ + INT cxWidth57; /* [Esc] width */ + INT cxWidth58; /* [Space] width */ + INT cyDefHeight; /* Regular key height */ + INT cyHeight50; /* [Enter] height */ + POINT KeyPos[T1K_MAX]; /* T1K --> POINT */ + WCHAR chKeyChar[48]; /* T1K --> WCHAR */ + HBITMAP hbmKeyboard; /* The keyboard image */ + DWORD CharSet; /* LOGFONT.lfCharSet */ + UINT PressedKey; /* Currently pressed key */ + POINT pt0, pt1; /* The soft keyboard window position */ + LPARAM KeyboardSubType; /* See IMC_GETSOFTKBDSUBTYPE/IMC_SETSOFTKBDSUBTYPE */ +} T1WINDOW, *PT1WINDOW; + +#define T1_KEYPOS(iKey) pT1->KeyPos[iKey] + +static LOGFONTW g_T1LogFont; + +static void +T1_GetTextMetric(_Out_ LPTEXTMETRICW ptm) +{ + WCHAR wch; + SIZE textSize; + HFONT hFont; + HGDIOBJ hFontOld; + HDC hDC; +#ifndef NDEBUG + WCHAR szFace[LF_FACESIZE]; +#endif + + ZeroMemory(&g_T1LogFont, sizeof(g_T1LogFont)); + g_T1LogFont.lfHeight = -12; + g_T1LogFont.lfWeight = FW_NORMAL; + g_T1LogFont.lfCharSet = CHINESEBIG5_CHARSET; +#ifdef NO_HACK /* FIXME: We lack proper Asian fonts! */ + g_T1LogFont.lfOutPrecision = OUT_TT_ONLY_PRECIS; + g_T1LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + g_T1LogFont.lfQuality = PROOF_QUALITY; + g_T1LogFont.lfPitchAndFamily = FF_MODERN | FIXED_PITCH; +#else + StringCchCopyW(g_T1LogFont.lfFaceName, _countof(g_T1LogFont.lfFaceName), L"MS Shell Dlg"); +#endif + hFont = CreateFontIndirectW(&g_T1LogFont); + + hDC = GetDC(NULL); + hFontOld = SelectObject(hDC, hFont); + +#ifndef NDEBUG + GetTextFaceW(hDC, _countof(szFace), szFace); + TRACE("szFace: %s\n", debugstr_w(szFace)); +#endif + + GetTextMetricsW(hDC, ptm); + + wch = 0x4E11; /* U+4E11: 丑 */ + if (GetTextExtentPoint32W(hDC, &wch, 1, &textSize) && textSize.cx > ptm->tmMaxCharWidth) + ptm->tmMaxCharWidth = textSize.cx; + + DeleteObject(SelectObject(hDC, hFontOld)); + ReleaseDC(NULL, hDC); +} + +static void +T1_InitButtonPos(_Out_ PT1WINDOW pT1) +{ + TEXTMETRICW tm; + LONG cxLarge, cyLarge; + LONG xKey1, yKey1, xKey2, yKey2, xKey3, yKey3; + LONG yKey4, xKey4, xKey5, yKey5, xKey6, xKey7; + INT iKey; + + T1_GetTextMetric(&tm); + + cxLarge = (3 * tm.tmMaxCharWidth + 18) / 2; + cyLarge = tm.tmHeight + 8; + + /* key widths and heights */ + pT1->cxDefWidth = (2 * tm.tmMaxCharWidth + 12) / 2; + pT1->cxWidth47 = (2 * tm.tmMaxCharWidth + 12) / 2 + 1; + pT1->cxWidth49 = (4 * tm.tmMaxCharWidth + 24) / 2 + 3; + pT1->cxWidth51or52 = (5 * tm.tmMaxCharWidth + 30) / 2 + 5; + pT1->cxWidth58 = 4 * (3 * tm.tmMaxCharWidth + 18) / 2 + 15; + pT1->cxWidth48 = pT1->cxWidth50 = cxLarge + 2; + pT1->cxWidth53or54 = pT1->cxWidth55or56 = cxLarge + 2; + pT1->cyHeight50 = 2 * (tm.tmHeight + 8) + 3; + pT1->cxWidth57 = cxLarge + 1; + pT1->cyDefHeight = cyLarge; + + /* First row */ + xKey1 = gptRaiseEdge.x + 3; + yKey1 = gptRaiseEdge.y + 3; + for (iKey = 0; iKey < T1K_Q; ++iKey) + { + T1_KEYPOS(iKey).x = xKey1; + T1_KEYPOS(iKey).y = yKey1; + xKey1 += pT1->cxDefWidth + 3; + } + T1_KEYPOS(T1K_BACKSPACE).y = yKey1; + T1_KEYPOS(T1K_BACKSPACE).x = xKey1; + + /* 2nd row */ + xKey2 = 3 + gptRaiseEdge.x + pT1->cxWidth48 + 3; + yKey2 = 3 + yKey1 + cyLarge; + T1_KEYPOS(T1K_TAB).x = gptRaiseEdge.x + 3; + T1_KEYPOS(T1K_TAB).y = yKey2; + for (iKey = T1K_Q; iKey < T1K_A; ++iKey) + { + T1_KEYPOS(iKey).x = xKey2; + T1_KEYPOS(iKey).y = yKey2; + xKey2 += pT1->cxDefWidth + 3; + } + T1_KEYPOS(T1K_ENTER).x = xKey2; + T1_KEYPOS(T1K_ENTER).y = yKey2; + + /* 3rd row */ + xKey3 = gptRaiseEdge.x + 3 + pT1->cxWidth49 + 3; + yKey3 = yKey2 + cyLarge + 3; + T1_KEYPOS(T1K_CAPS).x = gptRaiseEdge.x + 3; + T1_KEYPOS(T1K_CAPS).y = yKey3; + for (iKey = T1K_A; iKey < T1K_Z; ++iKey) + { + T1_KEYPOS(iKey).x = xKey3; + T1_KEYPOS(iKey).y = yKey3; + xKey3 += pT1->cxDefWidth + 3; + } + + /* 4th row */ + xKey4 = gptRaiseEdge.x + pT1->cxWidth51or52 + 3 + 3; + yKey4 = yKey3 + cyLarge + 3; + T1_KEYPOS(T1K_L_SHIFT).x = gptRaiseEdge.x + 3; + T1_KEYPOS(T1K_L_SHIFT).y = yKey4; + for (iKey = T1K_Z; iKey < T1K_BACKSPACE; ++iKey) + { + T1_KEYPOS(iKey).x = xKey4; + T1_KEYPOS(iKey).y = yKey4; + xKey4 += pT1->cxDefWidth + 3; + } + T1_KEYPOS(T1K_R_SHIFT).x = xKey4; + T1_KEYPOS(T1K_R_SHIFT).y = yKey4; + + /* 5th row */ + xKey5 = gptRaiseEdge.x + 3 + pT1->cxWidth53or54 + 3; + T1_KEYPOS(T1K_L_CTRL).x = gptRaiseEdge.x + 3; + T1_KEYPOS(T1K_ESCAPE).x = xKey5; + T1_KEYPOS(T1K_L_ALT).x = xKey5 + pT1->cxWidth57 + 3; + + yKey5 = yKey4 + cyLarge + 3; + T1_KEYPOS(T1K_L_CTRL).y = T1_KEYPOS(T1K_ESCAPE).y = T1_KEYPOS(T1K_L_ALT).y = yKey5; + T1_KEYPOS(T1K_R_ALT).y = T1_KEYPOS(T1K_SPACE).y = T1_KEYPOS(T1K_R_CTRL).y = yKey5; + + xKey6 = xKey5 + pT1->cxWidth57 + 3 + pT1->cxWidth55or56 + 3; + T1_KEYPOS(T1K_SPACE).x = xKey6; + + xKey7 = xKey6 + pT1->cxWidth58 + 3; + T1_KEYPOS(T1K_R_ALT).x = xKey7; + T1_KEYPOS(T1K_R_CTRL).x = xKey7 + pT1->cxWidth57 + pT1->cxWidth55or56 + 6; +} + +/* Draw keyboard key edge */ +static void +T1_DrawConvexRect( + _In_ HDC hDC, + _In_ INT x, + _In_ INT y, + _In_ INT width, + _In_ INT height) +{ + HGDIOBJ hBlackPen = GetStockObject(BLACK_PEN); + HGDIOBJ hLtGrayBrush = GetStockObject(LTGRAY_BRUSH); + HGDIOBJ hGrayBrush = GetStockObject(GRAY_BRUSH); + INT dx = width + 4, dy = height + 4; + INT x0 = x - 2, y0 = y + height + 2; + + /* Face */ + SelectObject(hDC, hBlackPen); + SelectObject(hDC, hLtGrayBrush); + Rectangle(hDC, x0, y - 2, x0 + dx, y0); + + /* Rounded corners */ + PatBlt(hDC, x0, y - 2, 1, 1, PATCOPY); + PatBlt(hDC, x0, y0, 1, -1, PATCOPY); + PatBlt(hDC, x0 + dx, y - 2, -1, 1, PATCOPY); + PatBlt(hDC, x0 + dx, y0, -1, -1, PATCOPY); + + /* Light edge */ + PatBlt(hDC, x0 + 1, y + dy - 3, 1, 2 - dy, WHITENESS); + PatBlt(hDC, x0 + 1, y - 1, dx - 2, 1, WHITENESS); + + /* Dark edge */ + SelectObject(hDC, hGrayBrush); + PatBlt(hDC, x0 + 1, y + dy - 3, dx - 2, -1, PATCOPY); + PatBlt(hDC, x0 + dx - 1, y + dy - 3, -1, 2 - dy, PATCOPY); +} + +static void +T1_DrawBitmap( + _In_ HDC hDC, + _In_ INT x, + _In_ INT y, + _In_ INT cx, + _In_ INT cy, + _In_ INT nBitmapID) +{ + HBITMAP hBitmap = LoadBitmapW(ghImm32Inst, MAKEINTRESOURCEW(nBitmapID)); + HDC hMemDC = CreateCompatibleDC(hDC); + HGDIOBJ hbmOld = SelectObject(hMemDC, hBitmap); + BitBlt(hDC, x, y, cx, cy, hMemDC, 0, 0, SRCCOPY); + SelectObject(hMemDC, hbmOld); + DeleteObject(hBitmap); + DeleteDC(hMemDC); +} + +static void +T1_DrawLabels( + _In_ HDC hDC, + _In_ const T1WINDOW *pT1, + _In_ LPCWSTR pszBmpName) +{ + HBITMAP hBitmap = LoadBitmapW(ghImm32Inst, pszBmpName); + HDC hdcMem = CreateCompatibleDC(hDC); + HGDIOBJ hbmOld = SelectObject(hdcMem, hBitmap); + INT iKey; + for (iKey = 0; iKey < T1K_BACKSPACE; ++iKey) + { + const POINT *ppt = &T1_KEYPOS(iKey); + BitBlt(hDC, ppt->x, ppt->y, 8, 8, hdcMem, iKey * 8, 0, SRCCOPY); + } + SelectObject(hdcMem, hbmOld); + DeleteDC(hdcMem); + DeleteObject(hBitmap); +} + +static void +T1_InitBitmap( + _In_ HWND hWnd, + _Inout_ PT1WINDOW pT1) +{ + HDC hDC, hMemDC; + HGDIOBJ hNullPen = GetStockObject(NULL_PEN), hbrLtGray = GetStockObject(LTGRAY_BRUSH); + RECT rc; + INT iKey; + + /* Create the bitmap */ + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + GetClientRect(hWnd, &rc); + pT1->hbmKeyboard = CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top); + ReleaseDC(hWnd, hDC); + + /* Draw keyboard face */ + SelectObject(hMemDC, pT1->hbmKeyboard); + SelectObject(hMemDC, hNullPen); + SelectObject(hMemDC, hbrLtGray); + Rectangle(hMemDC, rc.left, rc.top, rc.right + 1, rc.bottom + 1); + DrawEdge(hMemDC, &rc, EDGE_RAISED, BF_RECT); + + /* 53 --> Left [Ctrl] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_L_CTRL).x, T1_KEYPOS(T1K_L_CTRL).y, + pT1->cxWidth53or54, pT1->cyDefHeight); + T1_DrawBitmap(hMemDC, + pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_L_CTRL).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_CTRL).y - 4, + 16, 9, IDB_T1_CTRL); + + /* 54 --> Right [Ctrl] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_R_CTRL).x, T1_KEYPOS(T1K_R_CTRL).y, + pT1->cxWidth53or54, pT1->cyDefHeight); + T1_DrawBitmap(hMemDC, + pT1->cxWidth53or54 / 2 + T1_KEYPOS(T1K_R_CTRL).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_CTRL).y - 4, + 16, 9, IDB_T1_CTRL); + + /* 57 --> [Esc] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_ESCAPE).x, T1_KEYPOS(T1K_ESCAPE).y, + pT1->cxWidth57, pT1->cyDefHeight); + T1_DrawBitmap(hMemDC, + pT1->cxWidth57 / 2 + T1_KEYPOS(T1K_ESCAPE).x - 9, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_ESCAPE).y - 4, + 18, 9, IDB_T1_ESCAPE); + + /* 55 --> Left [Alt] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_L_ALT).x, T1_KEYPOS(T1K_L_ALT).y, + pT1->cxWidth55or56, pT1->cyDefHeight); + T1_DrawBitmap(hMemDC, + pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_L_ALT).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_ALT).y - 4, + 16, 9, IDB_T1_ALT); + + /* 56 --> Right [Alt] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_R_ALT).x, T1_KEYPOS(T1K_R_ALT).y, + pT1->cxWidth55or56, pT1->cyDefHeight); + T1_DrawBitmap(hMemDC, + pT1->cxWidth55or56 / 2 + T1_KEYPOS(T1K_R_ALT).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_ALT).y - 4, + 16, 9, IDB_T1_ALT); + + /* 58 --> [Space] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_SPACE).x, T1_KEYPOS(T1K_SPACE).y, + pT1->cxWidth58, pT1->cyDefHeight); + + /* 51 --> Left [Shift] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_L_SHIFT).x, T1_KEYPOS(T1K_L_SHIFT).y, + pT1->cxWidth51or52, pT1->cyDefHeight); + T1_DrawBitmap(hMemDC, + pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_L_SHIFT).x - 11, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_L_SHIFT).y - 4, + 23, 9, IDB_T1_SHIFT); + + /* 52 --> Right [Shift] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_R_SHIFT).x, T1_KEYPOS(T1K_R_SHIFT).y, + pT1->cxWidth51or52, pT1->cyDefHeight); + T1_DrawBitmap(hMemDC, + pT1->cxWidth51or52 / 2 + T1_KEYPOS(T1K_R_SHIFT).x - 11, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_R_SHIFT).y - 4, + 23, 9, IDB_T1_SHIFT); + + /* 49 --> [Caps] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_CAPS).x, T1_KEYPOS(T1K_CAPS).y, + pT1->cxWidth49, pT1->cyDefHeight); + T1_DrawBitmap(hMemDC, + pT1->cxWidth49 / 2 + T1_KEYPOS(T1K_CAPS).x - 11, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_CAPS).y - 4, + 22, 9, IDB_T1_CAPS); + + /* 48 --> [Tab] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_TAB).x, T1_KEYPOS(T1K_TAB).y, + pT1->cxWidth48, pT1->cyDefHeight); + T1_DrawBitmap(hMemDC, + pT1->cxWidth48 / 2 + T1_KEYPOS(T1K_TAB).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_TAB).y - 4, + 16, 9, IDB_T1_TAB); + + /* 50 --> [Enter] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_ENTER).x, T1_KEYPOS(T1K_ENTER).y, + pT1->cxWidth50, pT1->cyHeight50); + T1_DrawBitmap(hMemDC, + pT1->cxWidth50 / 2 + T1_KEYPOS(T1K_ENTER).x - 13, + pT1->cyHeight50 / 2 + T1_KEYPOS(T1K_ENTER).y - 4, + 26, 9, IDB_T1_ENTER); + + /* 47 --> [BackSpace] */ + T1_DrawConvexRect(hMemDC, + T1_KEYPOS(T1K_BACKSPACE).x, T1_KEYPOS(T1K_BACKSPACE).y, + pT1->cxWidth47, pT1->cyDefHeight); + T1_DrawBitmap(hMemDC, + pT1->cxWidth47 / 2 + T1_KEYPOS(T1K_BACKSPACE).x - 8, + pT1->cyDefHeight / 2 + T1_KEYPOS(T1K_BACKSPACE).y - 4, + 16, 9, IDB_T1_BACKSPACE); + + /* Regular keys */ + for (iKey = 0; iKey < T1K_BACKSPACE; ++iKey) + { + LPPOINT ppt = &T1_KEYPOS(iKey); + T1_DrawConvexRect(hMemDC, ppt->x, ppt->y, pT1->cxDefWidth, pT1->cyDefHeight); + } + + T1_DrawLabels(hMemDC, pT1, MAKEINTRESOURCEW(IDB_T1_CHARS)); + DeleteDC(hMemDC); +} + +static INT +T1_OnCreate( + _In_ HWND hWnd) +{ + PT1WINDOW pT1; + HGLOBAL hGlobal = GlobalAlloc(GHND, sizeof(T1WINDOW)); + if (!hGlobal) + return -1; + + pT1 = (PT1WINDOW)GlobalLock(hGlobal); + if (!pT1) + { + GlobalFree(hGlobal); + return -1; + } + + SetWindowLongPtrW(hWnd, 0, (LONG_PTR)hGlobal); + pT1->pt1.x = pT1->pt1.y = -1; + pT1->PressedKey = T1K_NONE; + pT1->CharSet = CHINESEBIG5_CHARSET; + + T1_InitButtonPos(pT1); + T1_InitBitmap(hWnd, pT1); + GlobalUnlock(hGlobal); + + return 0; +} + +static void +T1_DrawDragBorder( + _In_ HWND hWnd, + _In_ const POINT *ppt1, + _In_ const POINT *ppt2) +{ + INT cxBorder = GetSystemMetrics(SM_CXBORDER), cyBorder = GetSystemMetrics(SM_CYBORDER); + INT x = ppt1->x - ppt2->x, y = ppt1->y - ppt2->y; + HGDIOBJ hGrayBrush = GetStockObject(GRAY_BRUSH); + RECT rc; + HDC hDisplayDC; + + GetWindowRect(hWnd, &rc); + hDisplayDC = CreateDCW(L"DISPLAY", NULL, NULL, NULL); + SelectObject(hDisplayDC, hGrayBrush); + PatBlt(hDisplayDC, x, y, rc.right - rc.left - cxBorder, cyBorder, PATINVERT); + PatBlt(hDisplayDC, x, cyBorder + y, cxBorder, rc.bottom - rc.top - cyBorder, PATINVERT); + PatBlt(hDisplayDC, x + cxBorder, y + rc.bottom - rc.top, rc.right - rc.left - cxBorder, -cyBorder, PATINVERT); + PatBlt(hDisplayDC, x + rc.right - rc.left, y, -cxBorder, rc.bottom - rc.top - cyBorder, PATINVERT); + DeleteDC(hDisplayDC); +} + +static void +T1_OnDestroy( + _In_ HWND hWnd) +{ + HGLOBAL hGlobal; + PT1WINDOW pT1; + HWND hwndOwner; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pT1 = (PT1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pT1) + return; + + if (pT1->pt1.x != -1 && pT1->pt1.y != -1) + T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1); + + DeleteObject(pT1->hbmKeyboard); + GlobalUnlock(hGlobal); + GlobalFree(hGlobal); + + hwndOwner = GetWindow(hWnd, GW_OWNER); + if (hwndOwner) + SendMessageW(hwndOwner, WM_IME_NOTIFY, IMN_SOFTKBDDESTROYED, 0); +} + +static void +T1_InvertButton( + _In_ HWND hWnd, + _In_ HDC hDC, + _In_ const T1WINDOW *pT1, + _In_ UINT iPressed) +{ + INT cxWidth = pT1->cxDefWidth, cyHeight = pT1->cyDefHeight; + HDC hChoiceDC; + + if (iPressed >= T1K_NONE) + return; + + if (hDC) + hChoiceDC = hDC; + else + hChoiceDC = GetDC(hWnd); + + if (iPressed >= T1K_BACKSPACE) + { + switch (iPressed) + { + case T1K_BACKSPACE: + cxWidth = pT1->cxWidth47; + break; + case T1K_TAB: + cxWidth = pT1->cxWidth48; + break; + case T1K_ENTER: + pT1 = pT1; + cxWidth = pT1->cxWidth50; + cyHeight = pT1->cyHeight50; + break; + case T1K_ESCAPE: + cxWidth = pT1->cxWidth57; + break; + case T1K_SPACE: + cxWidth = pT1->cxWidth58; + break; + default: + cxWidth = 0; + MessageBeep(0xFFFFFFFF); + break; + } + } + + if (cxWidth > 0) + { + PatBlt(hChoiceDC, + T1_KEYPOS(iPressed).x - 1, T1_KEYPOS(iPressed).y - 1, + cxWidth + 2, cyHeight + 2, + DSTINVERT); + } + + if (!hDC) + ReleaseDC(hWnd, hChoiceDC); +} + +static void +T1_OnDraw( + _In_ HDC hDC, + _In_ HWND hWnd) +{ + HGLOBAL hGlobal; + PT1WINDOW pT1; + HDC hMemDC; + RECT rc; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pT1 = (PT1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pT1) + return; + + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, pT1->hbmKeyboard); + GetClientRect(hWnd, &rc); + BitBlt(hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + + if (pT1->PressedKey < T1K_NONE) + T1_InvertButton(hWnd, hDC, pT1, pT1->PressedKey); + + GlobalUnlock(hGlobal); +} + +static UINT +T1_HitTest( + _In_ const T1WINDOW *pT1, + _In_ const POINT *ppt) +{ + INT iKey; + for (iKey = 0; iKey < T1K_BACKSPACE; ++iKey) + { + const POINT *pptKey = &T1_KEYPOS(iKey); + if (Imm32PtInRect(ppt, pptKey->x, pptKey->y, pT1->cxDefWidth, pT1->cyDefHeight)) + return iKey; + } + + if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_BACKSPACE).x, T1_KEYPOS(T1K_BACKSPACE).y, pT1->cxWidth47, pT1->cyDefHeight)) + return T1K_BACKSPACE; + + if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_TAB).x, T1_KEYPOS(T1K_TAB).y, pT1->cxWidth48, pT1->cyDefHeight)) + return T1K_TAB; + + if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_CAPS).x, T1_KEYPOS(T1K_CAPS).y, pT1->cxWidth49, pT1->cyDefHeight)) + return T1K_CAPS; + + if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_ENTER).x, T1_KEYPOS(T1K_ENTER).y, pT1->cxWidth50, pT1->cyHeight50)) + return T1K_ENTER; + + if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_L_SHIFT).x, T1_KEYPOS(T1K_L_SHIFT).y, pT1->cxWidth51or52, pT1->cyDefHeight) || + Imm32PtInRect(ppt, T1_KEYPOS(T1K_R_SHIFT).x, T1_KEYPOS(T1K_R_SHIFT).y, pT1->cxWidth51or52, pT1->cyDefHeight)) + { + return T1K_L_SHIFT; + } + + if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_L_CTRL).x, T1_KEYPOS(T1K_L_CTRL).y, pT1->cxWidth53or54, pT1->cyDefHeight) || + Imm32PtInRect(ppt, T1_KEYPOS(T1K_R_CTRL).x, T1_KEYPOS(T1K_R_CTRL).y, pT1->cxWidth53or54, pT1->cyDefHeight)) + { + return T1K_L_CTRL; + } + + if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_L_ALT).x, T1_KEYPOS(T1K_L_ALT).y, pT1->cxWidth55or56, pT1->cyDefHeight) || + Imm32PtInRect(ppt, T1_KEYPOS(T1K_R_ALT).x, T1_KEYPOS(T1K_R_ALT).y, pT1->cxWidth55or56, pT1->cyDefHeight)) + { + return T1K_L_ALT; + } + + if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_ESCAPE).x, T1_KEYPOS(T1K_ESCAPE).y, pT1->cxWidth57, pT1->cyDefHeight)) + return T1K_ESCAPE; + + if (Imm32PtInRect(ppt, T1_KEYPOS(T1K_SPACE).x, T1_KEYPOS(T1K_SPACE).y, pT1->cxWidth58, pT1->cyDefHeight)) + return T1K_SPACE; + + return T1K_NONE; +} + +static BOOL +T1_IsValidButton( + _In_ UINT iKey, + _In_ const T1WINDOW *pT1) +{ + if (iKey < T1K_BACKSPACE) + return !!pT1->chKeyChar[iKey]; + return iKey <= T1K_TAB || iKey == T1K_ENTER || (T1K_ESCAPE <= iKey && iKey <= T1K_SPACE); +} + +/** + * NOTE: The window that has WS_DISABLED style doesn't receive some mouse messages. + * Use WM_SETCURSOR handling to detect mouse events. + */ +static BOOL +T1_OnSetCursor( + _In_ HWND hWnd, + _In_ LPARAM lParam) +{ + HGLOBAL hGlobal; + PT1WINDOW pT1; + HCURSOR hCursor; + UINT iPressed, iKey; + RECT rc, rcWork; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pT1 = (PT1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pT1) + return FALSE; + + if (pT1->pt1.x != -1 && pT1->pt1.y != -1) + { + SetCursor(LoadCursorW(NULL, (LPCWSTR)IDC_SIZEALL)); + GlobalUnlock(hGlobal); + return TRUE; + } + + GetCursorPos(&pT1->pt0); + ScreenToClient(hWnd, &pT1->pt0); + + iKey = T1_HitTest(pT1, &pT1->pt0); + if (iKey >= T1K_NONE) + hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_SIZEALL); + else + hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_HAND); + SetCursor(hCursor); + + if (HIWORD(lParam) == WM_LBUTTONDOWN) + { + SetCapture(hWnd); + + iPressed = pT1->PressedKey; + if (iPressed < T1K_NONE) + { + UINT iVK = gT1K2VK[iPressed]; + keybd_event(iVK, guScanCode[iVK], KEYEVENTF_KEYUP, 0); + T1_InvertButton(hWnd, NULL, pT1, pT1->PressedKey); + pT1->PressedKey = T1K_NONE; + } + + if (iKey >= T1K_NONE) + { + Imm32GetAllMonitorSize(&rcWork); + GetCursorPos(&pT1->pt0); + GetWindowRect(hWnd, &rc); + pT1->pt1.x = pT1->pt0.x - rc.left; + pT1->pt1.y = pT1->pt0.y - rc.top; + T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1); + } + else if (T1_IsValidButton(iKey, pT1)) + { + UINT iVK = gT1K2VK[iKey]; + keybd_event(iVK, guScanCode[iVK], 0, 0); + pT1->PressedKey = iKey; + T1_InvertButton(hWnd, 0, pT1, iKey); + } + else + { + MessageBeep(0xFFFFFFFF); + } + } + + return TRUE; +} + +static BOOL +T1_OnMouseMove( + _In_ HWND hWnd) +{ + BOOL ret = FALSE; + HGLOBAL hGlobal; + PT1WINDOW pT1; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pT1 = (PT1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pT1) + return FALSE; + + if (pT1->pt1.x != -1 && pT1->pt1.y != -1) + { + T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1); + GetCursorPos(&pT1->pt0); + T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1); + ret = TRUE; + } + + GlobalUnlock(hGlobal); + return ret; +} + +static BOOL +T1_OnButtonUp( + _In_ HWND hWnd) +{ + BOOL ret = FALSE; + HGLOBAL hGlobal; + PT1WINDOW pT1; + INT x, y, iPressed; + HWND hwndOwner, hwndCapture = GetCapture(); + HIMC hIMC; + LPINPUTCONTEXT pIC; + + if (hwndCapture == hWnd) + ReleaseCapture(); + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pT1 = (PT1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pT1) + return FALSE; + + iPressed = pT1->PressedKey; + if (iPressed >= T1K_NONE) + { + if (pT1->pt1.x != -1 && pT1->pt1.y != -1 ) + { + T1_DrawDragBorder(hWnd, &pT1->pt0, &pT1->pt1); + x = pT1->pt0.x - pT1->pt1.x; + y = pT1->pt0.y - pT1->pt1.y; + SetWindowPos(hWnd, NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); + pT1->pt1.x = pT1->pt1.y = -1; + pT1->PressedKey = T1K_NONE; + ret = TRUE; + + hwndOwner = GetWindow(hWnd, GW_OWNER); + hIMC = (HIMC)GetWindowLongPtrW(hwndOwner, 0); + if (hIMC) + { + pIC = ImmLockIMC(hIMC); + if (pIC) + { + pIC->fdwInit |= INIT_SOFTKBDPOS; + pIC->ptSoftKbdPos.x = x; + pIC->ptSoftKbdPos.y = y; + ImmUnlockIMC(hIMC); + } + } + } + } + else + { + UINT iVK = gT1K2VK[iPressed]; + keybd_event(iVK, guScanCode[iVK], KEYEVENTF_KEYUP, 0); + + T1_InvertButton(hWnd, 0, pT1, pT1->PressedKey); + pT1->PressedKey = T1K_NONE; + ret = TRUE; + } + + GlobalUnlock(hGlobal); + return ret; +} + +static LRESULT +T1_SetData( + _In_ HWND hWnd, + _In_ const SOFTKBDDATA *pData) +{ + HGLOBAL hGlobal; + PT1WINDOW pT1; + HDC hDC, hMemDC; + HFONT hFont; + HGDIOBJ hFontOld, hbmOld; + RECT rc; + INT iKey; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pT1 = (PT1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pT1) + return 1; + + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + ReleaseDC(hWnd, hDC); + + hbmOld = SelectObject(hMemDC, pT1->hbmKeyboard); +#if 0 /* The default text color is black */ + SetTextColor(hMemDC, RGB(0, 0, 0)); +#endif + SetBkColor(hMemDC, RGB(192, 192, 192)); + + if (pT1->CharSet == DEFAULT_CHARSET) + { + hFont = CreateFontIndirectW(&g_T1LogFont); + } + else + { + LOGFONTW lf = g_T1LogFont; + lf.lfCharSet = (BYTE)pT1->CharSet; + hFont = CreateFontIndirectW(&lf); + } + hFontOld = SelectObject(hMemDC, hFont); + + for (iKey = 0; iKey < T1K_BACKSPACE; ++iKey) + { + INT x0 = T1_KEYPOS(iKey).x, y0 = T1_KEYPOS(iKey).y; + INT x = x0 + 6, y = y0 + 8; + WCHAR wch = pT1->chKeyChar[iKey] = pData->wCode[0][gT1K2VK[iKey]]; + SetRect(&rc, x, y, x0 + pT1->cxDefWidth, y0 + pT1->cyDefHeight); + ExtTextOutW(hMemDC, x, y, ETO_OPAQUE, &rc, &wch, wch != 0, NULL); + } + + DeleteObject(SelectObject(hMemDC, hFontOld)); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + GlobalUnlock(hGlobal); + return 0; +} + +static LRESULT +T1_OnImeControl( + _In_ HWND hWnd, + _Inout_ WPARAM wParam, + _Inout_ LPARAM lParam) +{ + LRESULT ret = 1; + PT1WINDOW pT1; + HGLOBAL hGlobal; + + switch (wParam) + { + case IMC_GETSOFTKBDFONT: + { + TRACE("IMC_GETSOFTKBDFONT: %p\n", lParam); + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pT1 = (PT1WINDOW)GlobalLock(hGlobal); + if (hGlobal && pT1) + { + LPLOGFONTW plf = (LPLOGFONTW)lParam; + DWORD CharSet = pT1->CharSet; + GlobalUnlock(hGlobal); + + *plf = g_T1LogFont; + if (CharSet != DEFAULT_CHARSET) + plf->lfCharSet = (BYTE)CharSet; + + ret = 0; + } + break; + } + case IMC_SETSOFTKBDFONT: + { + const LOGFONTW *plf = (LPLOGFONTW)lParam; + TRACE("IMC_SETSOFTKBDFONT: %p\n", lParam); + if (g_T1LogFont.lfCharSet == plf->lfCharSet) + return 0; + + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pT1 = (PT1WINDOW)GlobalLock(hGlobal); + if (hGlobal && pT1) + { + pT1->CharSet = plf->lfCharSet; + GlobalUnlock(hGlobal); + return 0; + } + + break; + } + case IMC_GETSOFTKBDPOS: + { + RECT rc; + TRACE("IMC_GETSOFTKBDPOS\n"); + GetWindowRect(hWnd, &rc); + return MAKELRESULT(rc.left, rc.top); + } + case IMC_SETSOFTKBDPOS: + { + POINT pt; + HWND hwndParent; + + POINTSTOPOINT(pt, lParam); + TRACE("IMC_SETSOFTKBDPOS(%ld, %ld)\n", pt.x, pt.y); + + SetWindowPos(hWnd, NULL, pt.x, pt.y, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); + + hwndParent = GetParent(hWnd); + if (hwndParent) + { + HIMC hIMC = (HIMC)GetWindowLongPtrW(hwndParent, 0); + if (hIMC) + { + LPINPUTCONTEXT pIC = ImmLockIMC(hIMC); + if (pIC) + { + pIC->ptSoftKbdPos.x = pt.x; + pIC->ptSoftKbdPos.y = pt.y; + ImmUnlockIMC(hIMC); + return 0; + } + } + } + break; + } + case IMC_GETSOFTKBDSUBTYPE: + case IMC_SETSOFTKBDSUBTYPE: + { + TRACE("IMC_GETSOFTKBDSUBTYPE/IMC_SETSOFTKBDSUBTYPE\n"); + hGlobal = (HGLOBAL)GetWindowLongPtrW(hWnd, 0); + pT1 = (PT1WINDOW)GlobalLock(hGlobal); + if (!hGlobal || !pT1) + return -1; + + ret = pT1->KeyboardSubType; + + if (wParam == IMC_SETSOFTKBDSUBTYPE) + pT1->KeyboardSubType = lParam; + + GlobalUnlock(hGlobal); + break; + } + case IMC_SETSOFTKBDDATA: + { + TRACE("IMC_SETSOFTKBDDATA: %p\n", lParam); + ret = T1_SetData(hWnd, (SOFTKBDDATA*)lParam); + if (!ret) + { + InvalidateRect(hWnd, NULL, FALSE); + PostMessageW(hWnd, WM_PAINT, 0, 0); + } + break; + } + } + + return ret; +} + static LRESULT CALLBACK -SKWndProcT1(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +T1_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: { - FIXME("stub\n"); - return -1; + return T1_OnCreate(hWnd); + } + case WM_DESTROY: + { + T1_OnDestroy(hWnd); + break; + } + case WM_SETCURSOR: + { + if (T1_OnSetCursor(hWnd, lParam)) + break; + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + case WM_MOUSEMOVE: + { + if (T1_OnMouseMove(hWnd)) + break; + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + T1_OnDraw(hDC, hWnd); + EndPaint(hWnd, &ps); + break; + } + case WM_SHOWWINDOW: + { + if (!lParam && wParam != SW_SHOWNORMAL) + T1_OnButtonUp(hWnd); + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + case WM_MOUSEACTIVATE: + { + return MA_NOACTIVATE; + } + case WM_LBUTTONUP: + { + if (T1_OnButtonUp(hWnd)) + break; + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + case WM_IME_CONTROL: + { + return T1_OnImeControl(hWnd, wParam, lParam); } - default: { - return DefWindowProcW(hwnd, uMsg, wParam, lParam); + return DefWindowProcW(hWnd, uMsg, wParam, lParam); } } + return 0; } -/* Software keyboard window procedure (Simplified Chinese) */ +/***************************************************************************** + * IME Soft Keyboard Type C1 + */ + +#define C1_CLASSNAMEW L"SoftKBDClsC1" + static LRESULT CALLBACK -SKWndProcC1(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +C1_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { @@ -90,102 +1136,62 @@ SKWndProcC1(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) default: { - return DefWindowProcW(hwnd, uMsg, wParam, lParam); + return DefWindowProcW(hWnd, uMsg, wParam, lParam); } } return 0; } +/*****************************************************************************/ + static BOOL -Imm32RegisterSoftKeyboard(_In_ UINT uType) +Imm32RegisterSoftKeyboard( + _In_ UINT uType) { - LPCWSTR pszClass; WNDCLASSEXW wcx; - - if (uType == 1) - pszClass = L"SoftKBDClsT1"; - else if (uType == 2) - pszClass = L"SoftKBDClsC1"; - else - return FALSE; - + LPCWSTR pszClass = ((uType == SOFTKEYBOARD_TYPE_T1) ? T1_CLASSNAMEW : C1_CLASSNAMEW); if (GetClassInfoExW(ghImm32Inst, pszClass, &wcx)) return TRUE; ZeroMemory(&wcx, sizeof(wcx)); - wcx.cbSize = sizeof(wcx); - wcx.style = CS_IME; - wcx.cbWndExtra = sizeof(LONG_PTR); - wcx.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION); - wcx.hInstance = ghImm32Inst; - wcx.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_SIZEALL); + wcx.cbSize = sizeof(wcx); + wcx.style = CS_IME; + wcx.cbWndExtra = sizeof(PT1WINDOW); + wcx.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION); + wcx.hInstance = ghImm32Inst; + wcx.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_SIZEALL); wcx.lpszClassName = pszClass; - if (uType == 1) + if (uType == SOFTKEYBOARD_TYPE_T1) { - wcx.lpfnWndProc = SKWndProcT1; + wcx.lpfnWndProc = T1_WindowProc; wcx.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); } else { - wcx.lpfnWndProc = SKWndProcC1; + wcx.lpfnWndProc = C1_WindowProc; wcx.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); } return !!RegisterClassExW(&wcx); } -static VOID -Imm32GetSKT1TextMetric(_Out_ LPTEXTMETRICW lptm) -{ - HDC hDC; - HFONT hFont; - SIZE size; - HGDIOBJ hFontOld; - WCHAR szText[2] = { 0x894E, 0 }; - - hDC = GetDC(NULL); - - ZeroMemory(&s_lfSKT1Font, sizeof(s_lfSKT1Font)); - s_lfSKT1Font.lfHeight = -12; - s_lfSKT1Font.lfWeight = FW_NORMAL; - s_lfSKT1Font.lfCharSet = CHINESEBIG5_CHARSET; - s_lfSKT1Font.lfOutPrecision = OUT_TT_ONLY_PRECIS; - s_lfSKT1Font.lfClipPrecision = CLIP_DEFAULT_PRECIS; - s_lfSKT1Font.lfQuality = PROOF_QUALITY; - s_lfSKT1Font.lfPitchAndFamily = 49; - hFont = CreateFontIndirectW(&s_lfSKT1Font); - - hFontOld = SelectObject(hDC, hFont); - - GetTextMetricsW(hDC, lptm); - - if (GetTextExtentPoint32W(hDC, szText, 1, &size) && lptm->tmMaxCharWidth < size.cx ) - lptm->tmMaxCharWidth = size.cx; - - DeleteObject(SelectObject(hDC, hFontOld)); - ReleaseDC(NULL, hDC); -} - -static VOID +static void Imm32GetSoftKeyboardDimension( _In_ UINT uType, _Out_ LPINT pcx, _Out_ LPINT pcy) { - INT cxEdge, cyEdge; - TEXTMETRICW tm; - - if (uType == 1) + if (uType == SOFTKEYBOARD_TYPE_T1) { - Imm32GetSKT1TextMetric(&tm); - *pcx = 15 * tm.tmMaxCharWidth + 2 * s_ptRaiseEdge.x + 139; - *pcy = 5 * tm.tmHeight + 2 * s_ptRaiseEdge.y + 58; + TEXTMETRICW tm; + T1_GetTextMetric(&tm); + *pcx = 15 * tm.tmMaxCharWidth + 2 * gptRaiseEdge.x + 139; + *pcy = 5 * tm.tmHeight + 2 * gptRaiseEdge.y + 58; } else { - cxEdge = GetSystemMetrics(SM_CXEDGE); - cyEdge = GetSystemMetrics(SM_CYEDGE); + INT cxEdge = GetSystemMetrics(SM_CXEDGE), cyEdge = GetSystemMetrics(SM_CXEDGE); *pcx = 2 * (GetSystemMetrics(SM_CXBORDER) + cxEdge) + 348; *pcy = 2 * (GetSystemMetrics(SM_CYBORDER) + cyEdge) + 136; } @@ -205,65 +1211,85 @@ ImmCreateSoftKeyboard( { HKL hKL; PIMEDPI pImeDpi; - DWORD dwUICaps, style = (WS_POPUP | WS_DISABLED); - UINT i; - INT xSoftKBD, ySoftKBD, cxSoftKBD, cySoftKBD; + UINT iVK; + INT xSoftKBD, ySoftKBD, cxSoftKBD, cySoftKBD, cxEdge, cyEdge; HWND hwndSoftKBD; + DWORD Style, ExStyle, UICaps; + LPCWSTR pszClass; + RECT rcWorkArea; - TRACE("(%u, %p, %d, %d)\n", uType, hwndParent, x, y); - - if (uType != 1 && uType != 2) - return 0; + if ((uType != SOFTKEYBOARD_TYPE_T1) && (uType != SOFTKEYBOARD_TYPE_C1)) + { + ERR("uType: %u\n", uType); + return NULL; /* Invalid keyboard type */ + } + /* Check IME */ hKL = GetKeyboardLayout(0); pImeDpi = ImmLockImeDpi(hKL); - if (!pImeDpi) - return NULL; + if (IS_NULL_UNEXPECTEDLY(pImeDpi)) + return NULL; /* No IME */ - dwUICaps = pImeDpi->ImeInfo.fdwUICaps; + UICaps = pImeDpi->ImeInfo.fdwUICaps; ImmUnlockImeDpi(pImeDpi); - if (!(dwUICaps & UI_CAP_SOFTKBD)) - return NULL; - - if (s_bWannaInitSoftKBD) + /* Check IME capability */ + if (!(UICaps & UI_CAP_SOFTKBD)) { - if (!Imm32GetNearestMonitorSize(hwndParent, &s_rcWorkArea)) - return NULL; + ERR("UICaps: 0x%X\n", UICaps); + return NULL; /* No capability for soft keyboard */ + } - for (i = 0; i < 0xFF; ++i) - s_uScanCode[i] = MapVirtualKeyW(i, 0); + /* Want metrics? */ + if (g_bWantSoftKBDMetrics) + { + for (iVK = 0; iVK < 0xFF; ++iVK) + { + guScanCode[iVK] = MapVirtualKeyW(iVK, 0); + } - s_ptRaiseEdge.x = GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXEDGE); - s_ptRaiseEdge.y = GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYEDGE); + cxEdge = GetSystemMetrics(SM_CXEDGE); + cyEdge = GetSystemMetrics(SM_CYEDGE); + gptRaiseEdge.x = GetSystemMetrics(SM_CXBORDER) + cxEdge; + gptRaiseEdge.y = GetSystemMetrics(SM_CYBORDER) + cyEdge; - s_bWannaInitSoftKBD = FALSE; + g_bWantSoftKBDMetrics = FALSE; } + if (!Imm32GetNearestWorkArea(hwndParent, &rcWorkArea)) + return NULL; + + /* Register the window class */ if (!Imm32RegisterSoftKeyboard(uType)) + { + ERR("\n"); return NULL; + } + /* Calculate keyboard size */ Imm32GetSoftKeyboardDimension(uType, &cxSoftKBD, &cySoftKBD); - xSoftKBD = max(s_rcWorkArea.left, min(x, s_rcWorkArea.right - cxSoftKBD)); - ySoftKBD = max(s_rcWorkArea.top, min(y, s_rcWorkArea.bottom - cySoftKBD)); + /* Adjust keyboard position */ + xSoftKBD = Imm32Clamp(x, rcWorkArea.left, rcWorkArea.right - cxSoftKBD); + ySoftKBD = Imm32Clamp(y, rcWorkArea.top , rcWorkArea.bottom - cySoftKBD); - if (uType == 1) /* Traditional Chinese */ + /* Create soft keyboard window */ + if (uType == SOFTKEYBOARD_TYPE_T1) { - hwndSoftKBD = CreateWindowExW(0, - L"SoftKBDClsT1", NULL, style, - xSoftKBD, ySoftKBD, cxSoftKBD, cySoftKBD, - hwndParent, NULL, ghImm32Inst, NULL); + Style = (WS_POPUP | WS_DISABLED); + ExStyle = 0; + pszClass = T1_CLASSNAMEW; } - else /* Simplified Chinese (uType == 2) */ + else { - style |= WS_BORDER; - hwndSoftKBD = CreateWindowExW(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME, - L"SoftKBDClsC1", NULL, style, - xSoftKBD, ySoftKBD, cxSoftKBD, cySoftKBD, - hwndParent, NULL, ghImm32Inst, NULL); + Style = (WS_POPUP | WS_DISABLED | WS_BORDER); + ExStyle = (WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME); + pszClass = C1_CLASSNAMEW; } - + hwndSoftKBD = CreateWindowExW(ExStyle, pszClass, NULL, Style, + xSoftKBD, ySoftKBD, cxSoftKBD, cySoftKBD, + hwndParent, NULL, ghImm32Inst, NULL); + /* Initial is hidden */ ShowWindow(hwndSoftKBD, SW_HIDE); UpdateWindow(hwndSoftKBD); @@ -281,6 +1307,10 @@ ImmShowSoftKeyboard( _In_ INT nCmdShow) { TRACE("(%p, %d)\n", hwndSoftKBD, nCmdShow); + + if (nCmdShow != SW_HIDE && nCmdShow != SW_SHOWNOACTIVATE) + WARN("nCmdShow %d is unexpected\n", nCmdShow); + return hwndSoftKBD && ShowWindow(hwndSoftKBD, nCmdShow); } diff --git a/dll/win32/imm32/t1keys.h b/dll/win32/imm32/t1keys.h new file mode 100644 index 00000000000..22ed5b42469 --- /dev/null +++ b/dll/win32/imm32/t1keys.h @@ -0,0 +1,68 @@ +/* + * PROJECT: ReactOS IMM32 + * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later
) + * PURPOSE: Defining internal codes (T1K_...) of IME Soft Keyboard Type T1 + * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> + */ + +/* DEFINE_T1K(t1k_code, virtual_key_code, t1k_code_name, virtual_key_name, is_special) */ +DEFINE_T1K( 0, 0xC0, T1K_BACKTICK, VK_OEM_3, FALSE) +DEFINE_T1K( 1, 0x31, T1K_1, VK_1, FALSE) +DEFINE_T1K( 2, 0x32, T1K_2, VK_2, FALSE) +DEFINE_T1K( 3, 0x33, T1K_3, VK_3, FALSE) +DEFINE_T1K( 4, 0x34, T1K_4, VK_4, FALSE) +DEFINE_T1K( 5, 0x35, T1K_5, VK_5, FALSE) +DEFINE_T1K( 6, 0x36, T1K_6, VK_6, FALSE) +DEFINE_T1K( 7, 0x37, T1K_7, VK_7, FALSE) +DEFINE_T1K( 8, 0x38, T1K_8, VK_8, FALSE) +DEFINE_T1K( 9, 0x39, T1K_9, VK_9, FALSE) +DEFINE_T1K(10, 0x30, T1K_0, VK_0, FALSE) +DEFINE_T1K(11, 0xBD, T1K_MINUS, VK_OEM_MINUS, FALSE) +DEFINE_T1K(12, 0xBB, T1K_PLUS, VK_OEM_PLUS, FALSE) +DEFINE_T1K(13, 0xDC, T1K_OEM_5, VK_OEM_5, FALSE) +DEFINE_T1K(14, 0x51, T1K_Q, VK_Q, FALSE) +DEFINE_T1K(15, 0x57, T1K_W, VK_W, FALSE) +DEFINE_T1K(16, 0x45, T1K_E, VK_E, FALSE) +DEFINE_T1K(17, 0x52, T1K_R, VK_R, FALSE) +DEFINE_T1K(18, 0x54, T1K_T, VK_T, FALSE) +DEFINE_T1K(19, 0x59, T1K_Y, VK_Y, FALSE) +DEFINE_T1K(20, 0x55, T1K_U, VK_U, FALSE) +DEFINE_T1K(21, 0x49, T1K_I, VK_I, FALSE) +DEFINE_T1K(22, 0x4F, T1K_O, VK_O, FALSE) +DEFINE_T1K(23, 0x50, T1K_P, VK_P, FALSE) +DEFINE_T1K(24, 0xDB, T1K_OEM_4, VK_OEM_4, FALSE) +DEFINE_T1K(25, 0xDD, T1K_OEM_6, VK_OEM_6, FALSE) +DEFINE_T1K(26, 0x41, T1K_A, VK_A, FALSE) +DEFINE_T1K(27, 0x53, T1K_S, VK_S, FALSE) +DEFINE_T1K(28, 0x44, T1K_D, VK_D, FALSE) +DEFINE_T1K(29, 0x46, T1K_F, VK_F, FALSE) +DEFINE_T1K(30, 0x47, T1K_G, VK_G, FALSE) +DEFINE_T1K(31, 0x48, T1K_H, VK_H, FALSE) +DEFINE_T1K(32, 0x4A, T1K_J, VK_J, FALSE) +DEFINE_T1K(33, 0x4B, T1K_K, VK_K, FALSE) +DEFINE_T1K(34, 0x4C, T1K_L, VK_L, FALSE) +DEFINE_T1K(35, 0xBA, T1K_OEM_1, VK_OEM_1, FALSE) +DEFINE_T1K(36, 0xDE, T1K_OEM_7, VK_OEM_7, FALSE) +DEFINE_T1K(37, 0x5A, T1K_Z, VK_Z, FALSE) +DEFINE_T1K(38, 0x58, T1K_X, VK_X, FALSE) +DEFINE_T1K(39, 0x43, T1K_C, VK_C, FALSE) +DEFINE_T1K(40, 0x56, T1K_V, VK_V, FALSE) +DEFINE_T1K(41, 0x42, T1K_B, VK_B, FALSE) +DEFINE_T1K(42, 0x4E, T1K_N, VK_N, FALSE) +DEFINE_T1K(43, 0x4D, T1K_M, VK_M, FALSE) +DEFINE_T1K(44, 0xBC, T1K_OEM_COMMA, VK_OEM_COMMA, FALSE) +DEFINE_T1K(45, 0xBE, T1K_OEM_PERIOD, VK_OEM_PERIOD, FALSE) +DEFINE_T1K(46, 0xBF, T1K_OEM_2, VK_OEM_2, FALSE) +DEFINE_T1K(47, 0x08, T1K_BACKSPACE, VK_BACK, TRUE) +DEFINE_T1K(48, 0x09, T1K_TAB, VK_TAB, TRUE) +DEFINE_T1K(49, 0x14, T1K_CAPS, VK_CAPITAL, TRUE) +DEFINE_T1K(50, 0x0D, T1K_ENTER, VK_RETURN, TRUE) +DEFINE_T1K(51, 0x10, T1K_L_SHIFT, VK_SHIFT, TRUE) +DEFINE_T1K(52, 0x10, T1K_R_SHIFT, VK_SHIFT, TRUE) +DEFINE_T1K(53, 0x11, T1K_L_CTRL, VK_CONTROL, TRUE) +DEFINE_T1K(54, 0x11, T1K_R_CTRL, VK_CONTROL, TRUE) +DEFINE_T1K(55, 0x12, T1K_L_ALT, VK_MENU, TRUE) +DEFINE_T1K(56, 0x12, T1K_R_ALT, VK_MENU, TRUE) +DEFINE_T1K(57, 0x1B, T1K_ESCAPE, VK_ESCAPE, TRUE) +DEFINE_T1K(58, 0x20, T1K_SPACE, VK_SPACE, TRUE) +DEFINE_T1K(59, 0x00, T1K_NONE, 0, TRUE) diff --git a/sdk/include/ddk/immdev.h b/sdk/include/ddk/immdev.h index 619ac609367..8a8586b774d 100644 --- a/sdk/include/ddk/immdev.h +++ b/sdk/include/ddk/immdev.h @@ -17,12 +17,23 @@ extern "C" { #endif +typedef struct tagSOFTKBDDATA +{ + UINT uCount; + WORD wCode[1][256]; +} SOFTKBDDATA, *PSOFTKBDDATA, *LPSOFTKBDDATA; + /* wParam for WM_IME_CONTROL */ #define IMC_GETCONVERSIONMODE 0x0001 #define IMC_GETSENTENCEMODE 0x0003 #define IMC_GETOPENSTATUS 0x0005 +#define IMC_GETSOFTKBDFONT 0x0011 +#define IMC_SETSOFTKBDFONT 0x0012 #define IMC_GETSOFTKBDPOS 0x0013 #define IMC_SETSOFTKBDPOS 0x0014 +#define IMC_GETSOFTKBDSUBTYPE 0x0015 +#define IMC_SETSOFTKBDSUBTYPE 0x0016 +#define IMC_SETSOFTKBDDATA 0x0018 /* wParam for WM_IME_SYSTEM */ #define IMS_NOTIFYIMESHOW 0x05 @@ -46,6 +57,9 @@ extern "C" { #define IMS_SETLANGBAND 0x23 #define IMS_UNSETLANGBAND 0x24 +/* wParam for WM_IME_NOTIFY */ +#define IMN_SOFTKBDDESTROYED 0x0011 + #define IMMGWL_IMC 0 #define IMMGWL_PRIVATE (sizeof(LONG)) @@ -59,7 +73,7 @@ typedef struct _tagINPUTCONTEXT { POINT ptSoftKbdPos; DWORD fdwConversion; DWORD fdwSentence; - union { + union { LOGFONTA A; LOGFONTW W; } lfFont;
1 year, 1 month
1
0
0
0
[reactos] 01/01: [MSPAINT] Define SelectionBaseTool and use it (#6034)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f710e5a260d7798539424…
commit f710e5a260d77985394244e98aa57b3f5063c762 Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Fri Nov 24 15:44:16 2023 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Fri Nov 24 15:44:16 2023 +0900 [MSPAINT] Define SelectionBaseTool and use it (#6034) Refactoring and arrangement for selection handling. - Move some selection-related codes in canvas.cpp to mouse.cpp. - Add SelectionBaseTool structure for FreeSelTool and RectSelTool. CORE-19094 --- base/applications/mspaint/canvas.cpp | 72 +----- base/applications/mspaint/canvas.h | 5 - base/applications/mspaint/main.cpp | 30 +-- base/applications/mspaint/mouse.cpp | 366 ++++++++++++++++------------- base/applications/mspaint/selectionmodel.h | 1 - 5 files changed, 212 insertions(+), 262 deletions(-) diff --git a/base/applications/mspaint/canvas.cpp b/base/applications/mspaint/canvas.cpp index cf529e0f67d..fa6201cdf21 100644 --- a/base/applications/mspaint/canvas.cpp +++ b/base/applications/mspaint/canvas.cpp @@ -13,7 +13,6 @@ CCanvasWindow canvasWindow; CCanvasWindow::CCanvasWindow() : m_drawing(FALSE) - , m_hitSelection(HIT_NONE) , m_hitCanvasSizeBox(HIT_NONE) , m_ptOrig { -1, -1 } { @@ -316,25 +315,11 @@ LRESULT CCanvasWindow::OnButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO HITTEST hitSelection = selectionModel.hitTest(pt); if (hitSelection != HIT_NONE) { - selectionModel.m_nSelectionBrush = 0; // Selection Brush is OFF - if (bLeftButton) - { - CanvasToImage(pt); - if (::GetKeyState(VK_CONTROL) < 0) // Ctrl+Click is Selection Clone - { - imageModel.SelectionClone(); - } - else if (::GetKeyState(VK_SHIFT) < 0) // Shift+Dragging is Selection Brush - { - selectionModel.m_nSelectionBrush = 1; // Selection Brush is ON - } - StartSelectionDrag(hitSelection, pt); - } - else - { - ClientToScreen(&pt); - mainWindow.TrackPopupMenu(pt, 0); - } + m_drawing = TRUE; + CanvasToImage(pt); + SetCapture(); + toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, FALSE); + Invalidate(); return 0; } @@ -370,7 +355,7 @@ LRESULT CCanvasWindow::OnButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO m_drawing = TRUE; SetCapture(); toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, FALSE); - Invalidate(FALSE); + Invalidate(); return 0; } @@ -395,7 +380,7 @@ LRESULT CCanvasWindow::OnButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, B toolsModel.OnButtonDown(nMsg == WM_LBUTTONDBLCLK, pt.x, pt.y, TRUE); toolsModel.resetTool(); - Invalidate(FALSE); + Invalidate(); return 0; } @@ -418,12 +403,6 @@ LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL if (toolsModel.GetActiveTool() == TOOL_ZOOM) Invalidate(); - if (m_hitSelection != HIT_NONE) - { - SelectionDragging(pt); - return 0; - } - if (!m_drawing || toolsModel.GetActiveTool() <= TOOL_AIRBRUSH) { TRACKMOUSEEVENT tme = { sizeof(tme) }; @@ -444,7 +423,7 @@ LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL } } - if (m_drawing) + if (m_drawing || toolsModel.IsSelection()) { toolsModel.DrawWithMouseTool(pt, wParam); return 0; @@ -549,11 +528,6 @@ LRESULT CCanvasWindow::OnButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& ::SendMessageW(g_hStatusBar, SB_SETTEXT, 2, (LPARAM)L""); return 0; } - else if (m_hitSelection != HIT_NONE && bLeftButton) - { - EndSelectionDrag(pt); - return 0; - } if (m_hitCanvasSizeBox == HIT_NONE || !bLeftButton) return 0; @@ -728,7 +702,6 @@ VOID CCanvasWindow::cancelDrawing() { selectionModel.ClearColorImage(); selectionModel.ClearMaskImage(); - m_hitSelection = HIT_NONE; m_drawing = FALSE; toolsModel.OnEndDraw(TRUE); Invalidate(FALSE); @@ -741,35 +714,6 @@ VOID CCanvasWindow::finishDrawing() Invalidate(FALSE); } -VOID CCanvasWindow::StartSelectionDrag(HITTEST hit, POINT ptImage) -{ - m_hitSelection = hit; - selectionModel.m_ptHit = ptImage; - selectionModel.TakeOff(); - - SetCapture(); - Invalidate(FALSE); -} - -VOID CCanvasWindow::SelectionDragging(POINT ptImage) -{ - if (selectionModel.m_nSelectionBrush) - { - imageModel.SelectionClone(selectionModel.m_nSelectionBrush == 1); - selectionModel.m_nSelectionBrush = 2; // Selection Brush is ON and drawn - } - - selectionModel.Dragging(m_hitSelection, ptImage); - Invalidate(FALSE); -} - -VOID CCanvasWindow::EndSelectionDrag(POINT ptImage) -{ - selectionModel.Dragging(m_hitSelection, ptImage); - m_hitSelection = HIT_NONE; - Invalidate(FALSE); -} - LRESULT CCanvasWindow::OnCtlColorEdit(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { SetTextColor((HDC)wParam, paletteModel.GetFgColor()); diff --git a/base/applications/mspaint/canvas.h b/base/applications/mspaint/canvas.h index e59b37cc670..5bdd1def467 100644 --- a/base/applications/mspaint/canvas.h +++ b/base/applications/mspaint/canvas.h @@ -56,7 +56,6 @@ public: VOID zoomTo(INT newZoom, LONG left = 0, LONG top = 0); protected: - HITTEST m_hitSelection; HITTEST m_hitCanvasSizeBox; POINT m_ptOrig; // The origin of drag start HBITMAP m_ahbmCached[2]; // The cached buffer bitmaps @@ -67,10 +66,6 @@ protected: VOID DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint); VOID OnHVScroll(WPARAM wParam, INT fnBar); - VOID StartSelectionDrag(HITTEST hit, POINT ptImage); - VOID SelectionDragging(POINT ptImage); - VOID EndSelectionDrag(POINT ptImage); - LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnVScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); diff --git a/base/applications/mspaint/main.cpp b/base/applications/mspaint/main.cpp index 535db5b42c8..7e3364678f1 100644 --- a/base/applications/mspaint/main.cpp +++ b/base/applications/mspaint/main.cpp @@ -963,29 +963,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH textEditWindow.PostMessage(WM_UNDO, 0, 0); break; } - if (selectionModel.m_bShow) - { - if (toolsModel.IsSelection()) - { - canvasWindow.cancelDrawing(); - if (toolsModel.GetActiveTool() == TOOL_FREESEL || - toolsModel.GetActiveTool() == TOOL_RECTSEL) - { - imageModel.Undo(); - if (selectionModel.m_nSelectionBrush == 2) // Selection Brush is drawn - { - imageModel.Undo(); - selectionModel.m_nSelectionBrush = 0; - } - } - break; - } - } - if (ToolBase::s_pointSP != 0) // drawing something? - { - canvasWindow.cancelDrawing(); - break; - } + canvasWindow.finishDrawing(); imageModel.Undo(); break; case IDM_EDITREDO: @@ -994,11 +972,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH // There is no "WM_REDO" in EDIT control break; } - if (ToolBase::s_pointSP != 0) // drawing something? - { - canvasWindow.finishDrawing(); - break; - } + canvasWindow.finishDrawing(); imageModel.Redo(); break; case IDM_EDITCOPY: diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp index 625834b1c0c..2dcec274e80 100644 --- a/base/applications/mspaint/mouse.cpp +++ b/base/applications/mspaint/mouse.cpp @@ -121,170 +121,6 @@ void ToolBase::pushToPtStack(LONG x, LONG y) /* TOOLS ********************************************************/ -// TOOL_FREESEL -struct FreeSelTool : ToolBase -{ - BOOL m_bLeftButton = FALSE; - - void OnDrawOverlayOnImage(HDC hdc) override - { - if (!selectionModel.IsLanded()) - selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); - - if (canvasWindow.m_drawing) - { - selectionModel.DrawFramePoly(hdc); - } - } - - void OnDrawOverlayOnCanvas(HDC hdc) override - { - selectionModel.drawFrameOnCanvas(hdc); - } - - void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override - { - selectionModel.Landing(); - if (bLeftButton) - { - selectionModel.HideSelection(); - selectionModel.ResetPtStack(); - POINT pt = { x, y }; - selectionModel.PushToPtStack(pt); - } - m_bLeftButton = bLeftButton; - } - - BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override - { - if (bLeftButton) - { - POINT pt = { x, y }; - imageModel.Clamp(pt); - selectionModel.PushToPtStack(pt); - imageModel.NotifyImageChanged(); - } - return TRUE; - } - - BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override - { - if (bLeftButton) - { - if (selectionModel.PtStackSize() > 2) - { - selectionModel.BuildMaskFromPtStack(); - selectionModel.m_bShow = TRUE; - } - else - { - selectionModel.ResetPtStack(); - selectionModel.m_bShow = FALSE; - } - imageModel.NotifyImageChanged(); - } - else - { - POINT pt = { x, y }; - canvasWindow.ClientToScreen(&pt); - mainWindow.TrackPopupMenu(pt, 0); - } - return TRUE; - } - - void OnEndDraw(BOOL bCancel) override - { - if (bCancel) - selectionModel.HideSelection(); - else - selectionModel.Landing(); - ToolBase::OnEndDraw(bCancel); - } - - void OnSpecialTweak(BOOL bMinus) override - { - selectionModel.StretchSelection(bMinus); - } -}; - -// TOOL_RECTSEL -struct RectSelTool : ToolBase -{ - BOOL m_bLeftButton = FALSE; - - void OnDrawOverlayOnImage(HDC hdc) override - { - if (!selectionModel.IsLanded()) - selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); - - if (canvasWindow.m_drawing) - { - CRect& rc = selectionModel.m_rc; - if (!rc.IsRectEmpty()) - RectSel(hdc, rc.left, rc.top, rc.right, rc.bottom); - } - } - - void OnDrawOverlayOnCanvas(HDC hdc) override - { - selectionModel.drawFrameOnCanvas(hdc); - } - - void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override - { - selectionModel.Landing(); - if (bLeftButton) - { - selectionModel.HideSelection(); - } - m_bLeftButton = bLeftButton; - } - - BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override - { - if (bLeftButton) - { - POINT pt = { x, y }; - imageModel.Clamp(pt); - selectionModel.SetRectFromPoints(g_ptStart, pt); - imageModel.NotifyImageChanged(); - } - return TRUE; - } - - BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override - { - POINT pt = { x, y }; - if (bLeftButton) - { - imageModel.Clamp(pt); - selectionModel.SetRectFromPoints(g_ptStart, pt); - selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty(); - imageModel.NotifyImageChanged(); - } - else - { - canvasWindow.ClientToScreen(&pt); - mainWindow.TrackPopupMenu(pt, 0); - } - return TRUE; - } - - void OnEndDraw(BOOL bCancel) override - { - if (bCancel) - selectionModel.HideSelection(); - else - selectionModel.Landing(); - ToolBase::OnEndDraw(bCancel); - } - - void OnSpecialTweak(BOOL bMinus) override - { - selectionModel.StretchSelection(bMinus); - } -}; - struct TwoPointDrawTool : ToolBase { BOOL m_bLeftButton = FALSE; @@ -491,6 +327,208 @@ struct SmoothDrawTool : ToolBase } }; +struct SelectionBaseTool : SmoothDrawTool +{ + BOOL m_bLeftButton = FALSE; + BOOL m_bCtrlKey = FALSE; + BOOL m_bShiftKey = FALSE; + BOOL m_bDrawing = FALSE; + HITTEST m_hitSelection = HIT_NONE; + + BOOL isRectSelect() const + { + return (toolsModel.GetActiveTool() == TOOL_RECTSEL); + } + + void OnDrawOverlayOnImage(HDC hdc) override + { + if (!selectionModel.IsLanded()) + selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); + } + + void OnDrawOverlayOnCanvas(HDC hdc) override + { + selectionModel.drawFrameOnCanvas(hdc); + } + + void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override + { + m_bLeftButton = bLeftButton; + m_bCtrlKey = (::GetKeyState(VK_CONTROL) < 0); + m_bShiftKey = (::GetKeyState(VK_SHIFT) < 0); + m_bDrawing = FALSE; + m_hitSelection = HIT_NONE; + + POINT pt = { x, y }; + if (!m_bLeftButton) // Show context menu on Right-click + { + canvasWindow.ImageToCanvas(pt); + canvasWindow.ClientToScreen(&pt); + mainWindow.TrackPopupMenu(pt, 0); + return; + } + + POINT ptCanvas = pt; + canvasWindow.ImageToCanvas(ptCanvas); + HITTEST hit = selectionModel.hitTest(ptCanvas); + if (hit != HIT_NONE) // Dragging of selection started? + { + if (m_bCtrlKey || m_bShiftKey) + imageModel.SelectionClone(); + + m_hitSelection = hit; + selectionModel.m_ptHit = pt; + selectionModel.TakeOff(); + + imageModel.NotifyImageChanged(); + return; + } + + selectionModel.Landing(); + m_bDrawing = TRUE; + + imageModel.Clamp(pt); + if (isRectSelect()) + { + selectionModel.SetRectFromPoints(g_ptStart, pt); + } + else + { + selectionModel.ResetPtStack(); + selectionModel.PushToPtStack(pt); + } + + imageModel.NotifyImageChanged(); + } + + BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override + { + POINT pt = { x, y }; + + if (!m_bLeftButton) + return TRUE; + + if (m_hitSelection != HIT_NONE) // Now dragging selection? + { + if (m_bShiftKey) + imageModel.SelectionClone(m_bShiftKey); + + selectionModel.Dragging(m_hitSelection, pt); + imageModel.NotifyImageChanged(); + return TRUE; + } + + imageModel.Clamp(pt); + if (isRectSelect()) + selectionModel.SetRectFromPoints(g_ptStart, pt); + else + selectionModel.PushToPtStack(pt); + + imageModel.NotifyImageChanged(); + return TRUE; + } + + BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override + { + POINT pt = { x, y }; + m_bDrawing = FALSE; + + if (!m_bLeftButton) + return TRUE; + + if (m_hitSelection != HIT_NONE) // Dragging of selection ended? + { + selectionModel.Dragging(m_hitSelection, pt); + m_hitSelection = HIT_NONE; + imageModel.NotifyImageChanged(); + return TRUE; + } + + imageModel.Clamp(pt); + if (isRectSelect()) + { + selectionModel.SetRectFromPoints(g_ptStart, pt); + selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty(); + } + else + { + if (selectionModel.PtStackSize() > 2) + { + selectionModel.BuildMaskFromPtStack(); + selectionModel.m_bShow = TRUE; + } + else + { + selectionModel.ResetPtStack(); + selectionModel.m_bShow = FALSE; + } + } + + imageModel.NotifyImageChanged(); + return TRUE; + } + + void OnEndDraw(BOOL bCancel) override + { + if (bCancel) + selectionModel.HideSelection(); + else + selectionModel.Landing(); + + m_hitSelection = HIT_NONE; + ToolBase::OnEndDraw(bCancel); + } + + void OnSpecialTweak(BOOL bMinus) override + { + selectionModel.StretchSelection(bMinus); + } +}; + +// TOOL_FREESEL +struct FreeSelTool : SelectionBaseTool +{ + void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override + { + if (m_bShiftKey && !m_bCtrlKey) + { + // TODO: + } + } + + void OnDrawOverlayOnImage(HDC hdc) override + { + SelectionBaseTool::OnDrawOverlayOnImage(hdc); + + if (!selectionModel.m_bShow && m_bDrawing) + selectionModel.DrawFramePoly(hdc); + } +}; + +// TOOL_RECTSEL +struct RectSelTool : SelectionBaseTool +{ + void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override + { + if (m_bShiftKey && !m_bCtrlKey) + { + // TODO: + } + } + + void OnDrawOverlayOnImage(HDC hdc) override + { + SelectionBaseTool::OnDrawOverlayOnImage(hdc); + + if (!selectionModel.m_bShow && m_bDrawing) + { + CRect& rc = selectionModel.m_rc; + if (!rc.IsRectEmpty()) + RectSel(hdc, rc.left, rc.top, rc.right, rc.bottom); + } + } +}; + // TOOL_RUBBER struct RubberTool : SmoothDrawTool { diff --git a/base/applications/mspaint/selectionmodel.h b/base/applications/mspaint/selectionmodel.h index 37cf74ca38f..e83786191ff 100644 --- a/base/applications/mspaint/selectionmodel.h +++ b/base/applications/mspaint/selectionmodel.h @@ -23,7 +23,6 @@ public: CRect m_rc; // in image pixel coordinates POINT m_ptHit; // in image pixel coordinates CRect m_rcOld; // in image pixel coordinates - INT m_nSelectionBrush = 0; SelectionModel(); ~SelectionModel();
1 year, 1 month
1
0
0
0
[reactos] 01/01: [MSPAINT] Move CHECKED_IF and ENABLED_IF macros and improve
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=898fb5f414195931dd1a9…
commit 898fb5f414195931dd1a9fafb0fb1033c128c27a Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Fri Nov 24 10:39:16 2023 +0900 Commit: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> CommitDate: Fri Nov 24 10:39:16 2023 +0900 [MSPAINT] Move CHECKED_IF and ENABLED_IF macros and improve Refactoring. CORE-19094 --- base/applications/mspaint/precomp.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/base/applications/mspaint/precomp.h b/base/applications/mspaint/precomp.h index b98f40a11e6..f5efb4da77b 100644 --- a/base/applications/mspaint/precomp.h +++ b/base/applications/mspaint/precomp.h @@ -51,12 +51,6 @@ #define WM_TOOLSMODELZOOMCHANGED (WM_APP + 2) #define WM_PALETTEMODELCOLORCHANGED (WM_APP + 3) -/* this simplifies checking and unchecking menu items */ -#define CHECKED_IF(a) ((a) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND)) - -/* this simplifies enabling or graying menu items */ -#define ENABLED_IF(a) ((a) ? (MF_ENABLED | MF_BYCOMMAND) : (MF_GRAYED | MF_BYCOMMAND)) - enum HITTEST // hit { HIT_NONE = 0, // Nothing hit or outside @@ -82,6 +76,14 @@ void getBoundaryOfPtStack(RECT& rcBoundary, INT cPoints, const POINT *pPoints); #define DEG2RAD(degree) (((degree) * M_PI) / 180) #define RAD2DEG(radian) ((LONG)(((radian) * 180) / M_PI)) +/* This simplifies checking and unchecking menu items */ +#define CHECKED_IF(bChecked) \ + ((bChecked) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND)) + +/* This simplifies enabling or graying menu items */ +#define ENABLED_IF(bEnabled) \ + ((bEnabled) ? (MF_ENABLED | MF_BYCOMMAND) : (MF_GRAYED | MF_BYCOMMAND)) + template <typename T> inline void Swap(T& a, T& b) {
1 year, 1 month
1
0
0
0
← Newer
1
2
3
4
5
6
7
...
28
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Results per page:
10
25
50
100
200