diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 678053c..f83d51f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -977,6 +977,10 @@ add_test(NAME opus_word1_ui_test COMMAND $ $ ) set_tests_properties(opus_word1_ui_test PROPERTIES TIMEOUT 20) +add_test(NAME opus_word1_clipboard_shortcut_test + COMMAND $ $ --clipboard +) +set_tests_properties(opus_word1_clipboard_shortcut_test PROPERTIES TIMEOUT 20) add_test(NAME opus_word1_typing_test COMMAND $ $ --typing ) diff --git a/src/Opus/init2.c b/src/Opus/init2.c index edef863..9080d9f 100644 --- a/src/Opus/init2.c +++ b/src/Opus/init2.c @@ -502,6 +502,15 @@ BOOL fTutorial; AddKeyToKmp(hkmpBase, kcSubscript, bcmSubscript); AddKeyToKmp(hkmpBase, kcSuperscript, bcmSuperscript); AddKeyToKmp(hkmpBase, kcShowAll, bcmShowAll); +#ifdef OPUS_X64 + /* Word 95 editing accelerators. Register them in the original base + keymap so commands retain Word's normal selection/undo legality. */ + AddKeyToKmp(hkmpBase, KcCtrl('A'), bcmSelectAll); + AddKeyToKmp(hkmpBase, KcCtrl('C'), bcmCopy); + AddKeyToKmp(hkmpBase, KcCtrl('V'), bcmPaste); + AddKeyToKmp(hkmpBase, KcCtrl('X'), bcmCut); + AddKeyToKmp(hkmpBase, KcCtrl('Z'), bcmUndo); +#endif } Debug( vdbs.fReportHeap ? @@ -1281,8 +1290,10 @@ FCreateSysMenu() HDC hdcBitmap; HBITMAP hbmpOld; HPEN hpenOld; + HICON hiconDocument; int dxMenu; int dyMenu; + int dyIcon; dxMenu = GetSystemMetrics(SM_CXSMICON); dyMenu = GetSystemMetrics(SM_CYMENU); @@ -1310,12 +1321,26 @@ FCreateSysMenu() hbmpOld = SelectObject(hdcBitmap, hbmpSystem); PatBlt(hdcBitmap, 0, 0, dxMenu, dyMenu, WHITENESS); - hpenOld = SelectObject(hdcBitmap, GetStockObject(BLACK_PEN)); - MoveToEx(hdcBitmap, 3, 3, NULL); - LineTo(hdcBitmap, dxMenu - 3, dyMenu - 3); - MoveToEx(hdcBitmap, dxMenu - 4, 3, NULL); - LineTo(hdcBitmap, 2, dyMenu - 3); - SelectObject(hdcBitmap, hpenOld); + dyIcon = min(dxMenu, dyMenu); + hiconDocument = (HICON)LoadImage(vhInstance, MAKEINTRESOURCE(302), + IMAGE_ICON, dyIcon, dyIcon, LR_DEFAULTCOLOR); + if (hiconDocument != NULL) + { + DrawIconEx(hdcBitmap, (dxMenu - dyIcon) / 2, + (dyMenu - dyIcon) / 2, hiconDocument, dyIcon, dyIcon, + 0, NULL, DI_NORMAL); + DestroyIcon(hiconDocument); + } + else + { + /* Keep a recognizable fallback if the product resource is missing. */ + hpenOld = SelectObject(hdcBitmap, GetStockObject(BLACK_PEN)); + MoveToEx(hdcBitmap, 3, 3, NULL); + LineTo(hdcBitmap, dxMenu - 3, dyMenu - 3); + MoveToEx(hdcBitmap, dxMenu - 4, 3, NULL); + LineTo(hdcBitmap, 2, dyMenu - 3); + SelectObject(hdcBitmap, hpenOld); + } SelectObject(hdcBitmap, hbmpOld); DeleteDC(hdcBitmap); vsci.dxpBmpSystem = dxMenu; diff --git a/src/Opus/initwin.c b/src/Opus/initwin.c index 72967c7..7701c18 100644 --- a/src/Opus/initwin.c +++ b/src/Opus/initwin.c @@ -2159,9 +2159,14 @@ FInitHandles() vwWinVersion > 0x0299); #endif /* OPUS_X64 */ for (ilrd = 0; ilrd < ilrdRcdsIcoMax; ilrd++) - if ((*rglrdRcdsIco[ilrd].ph = fRes ? - LoadIcon(vhInstance, rglrdRcdsIco[ilrd].id+1) : + if ((*rglrdRcdsIco[ilrd].ph = +#ifdef OPUS_X64 + /* Native executable resource requested for the restored shell. */ + LoadIcon(vhInstance, MAKEINTRESOURCE(301))) +#else + fRes ? LoadIcon(vhInstance, rglrdRcdsIco[ilrd].id+1) : HLoadRes0(rglrdRcdsIco[ilrd].id)) +#endif == NULL) return fFalse; diff --git a/src/Opus/wordwin.h b/src/Opus/wordwin.h index c2c6478..c2c8de1 100644 --- a/src/Opus/wordwin.h +++ b/src/Opus/wordwin.h @@ -451,8 +451,11 @@ struct DRC { /* Key Map Entry */ typedef struct _kme { - int kc : 12; - int kt : 3; + /* These are encoded fields, not signed arithmetic values. Modern MSVC + sign-extends the historical plain-int bitfields (ktMacro 6 became -2), + which made every command key fail to dispatch in the 64-bit port. */ + unsigned kc : 12; + unsigned kt : 3; union { int w; /* generic */ BCM bcm; /* ktMacro */ diff --git a/src/Opus/wproc.c b/src/Opus/wproc.c index 343a24a..32dc161 100644 --- a/src/Opus/wproc.c +++ b/src/Opus/wproc.c @@ -1755,6 +1755,18 @@ LONG lParam; return (LRESULT)OpusGetWin95ZoomPercent(hwnd); case 79: return (LRESULT)selCur.chp.ico; + case 80: + { + extern BOOL FExecKc(); + return (LRESULT)FExecKc((int)lParam); + } + case 81: + { + extern KME * PkmeOfKcInChain(); + KME *pkme = PkmeOfKcInChain((int)lParam); + return (LRESULT)(pkme != 0 && pkme->kt == ktMacro + ? pkme->bcm : -1); + } } return (LRESULT) -1; #endif @@ -2545,7 +2557,11 @@ LInsert: /* Get current Ctrl key state; OurGetKeyState cannot be trusted (sez bradch(rp)) */ - vgrpfKeyBoardState |= (GetKeyState(VK_CONTROL)<0) ? wKbsControlMask : 0; + vgrpfKeyBoardState |= (GetKeyState(VK_CONTROL)<0 +#ifdef OPUS_X64 + || GetAsyncKeyState(VK_CONTROL)<0 +#endif + ) ? wKbsControlMask : 0; /* FUTURE: cursor keys will be in keymap someday... */ /* but because they're not, need to special case preview */ diff --git a/src/port/icons/ICON2_1.ico b/src/port/icons/ICON2_1.ico new file mode 100644 index 0000000..5f57f9a Binary files /dev/null and b/src/port/icons/ICON2_1.ico differ diff --git a/src/port/icons/ICON8_1.ico b/src/port/icons/ICON8_1.ico new file mode 100644 index 0000000..630dff2 Binary files /dev/null and b/src/port/icons/ICON8_1.ico differ diff --git a/src/port/original/opus_asm_movecmds.c b/src/port/original/opus_asm_movecmds.c index 0ad003a..76709d1 100644 --- a/src/port/original/opus_asm_movecmds.c +++ b/src/port/original/opus_asm_movecmds.c @@ -49,8 +49,8 @@ typedef struct _OPUS_NATIVE_SYT typedef struct _OPUS_NATIVE_KME { - int kc : 12; - int kt : 3; + unsigned kc : 12; + unsigned kt : 3; union { int w; void *pfn; diff --git a/src/port/word1.rc b/src/port/word1.rc index 5b79fab..9910e19 100644 --- a/src/port/word1.rc +++ b/src/port/word1.rc @@ -2,6 +2,8 @@ 1 RT_MANIFEST "winword.manifest" 201 BITMAP "assets\\word95-toolbar.bmp" +301 ICON "icons\\ICON8_1.ico" +302 ICON "icons\\ICON2_1.ico" VS_VERSION_INFO VERSIONINFO FILEVERSION 0,2,0,0