Index: base/applications/regedit/childwnd.c =================================================================== --- base/applications/regedit/childwnd.c (revision 48222) +++ base/applications/regedit/childwnd.c (working copy) @@ -587,8 +587,8 @@ } else pt.x = pt.y = 0; + ClientToScreen(pChildWnd->hListWnd, &pt); } - ClientToScreen(pChildWnd->hListWnd, &pt); if(i == -1) { TrackPopupMenu(GetSubMenu(hPopupMenus, PM_NEW), TPM_RIGHTBUTTON, pt.x, pt.y, 0, hFrameWnd, NULL); Index: base/applications/regedit/hexedit.c =================================================================== --- base/applications/regedit/hexedit.c (revision 48222) +++ base/applications/regedit/hexedit.c (working copy) @@ -47,9 +47,11 @@ INT SelStart; INT SelEnd; - BOOL SelOnField; } HEXEDIT_DATA, *PHEXEDIT_DATA; +static const TCHAR ClipboardFormatName[] = TEXT("RegEdit_HexData"); +static UINT ClipboardFormatID = 0; + /* hit test codes */ #define HEHT_LEFTMARGIN (0x1) #define HEHT_ADDRESS (0x2) @@ -67,6 +69,8 @@ { WNDCLASSEX WndClass; + ClipboardFormatID = RegisterClipboardFormat(ClipboardFormatName); + ZeroMemory(&WndClass, sizeof(WNDCLASSEX)); WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = CS_DBLCLKS; @@ -218,7 +222,7 @@ if(ScrollPos + First == 0) { /* draw address */ - _stprintf(addr, _T("%04X"), 0); + wsprintf(addr, TEXT("%04X"), 0); TextOut(hDC, hed->LeftMargin, First * hed->LineHeight, addr, 4); } } @@ -240,7 +244,7 @@ dx = hed->LeftMargin; /* draw address */ - _stprintf(addr, _T("%04lX"), linestart); + wsprintf(addr, TEXT("%04lX"), linestart); TextOut(hDC, dx, dy, addr, 4); dx += ((4 + hed->AddressSpacing) * hed->CharWidth); @@ -260,7 +264,7 @@ rct.left += dh; rct.right += dh; - _stprintf(hex, _T("%02X"), *(current++)); + wsprintf(hex, TEXT("%02X"), *(current++)); if (i0 <= i && i < i1) { rct2.left = dx; @@ -275,7 +279,7 @@ } else ExtTextOut(hDC, dx, dy, ETO_OPAQUE, &rct, hex, 2, NULL); - dx += dh; + dx += dh; i++; } @@ -285,8 +289,8 @@ i = isave; for(x = 0; x < hed->ColumnsPerLine && current < end; x++) { - _stprintf(hex, _T("%C"), *(current++)); - hex[0] = ((hex[0] & _T('\x007f')) >= _T(' ') ? hex[0] : _T('.')); + wsprintf(hex, _T("%C"), *(current++)); + hex[0] = ((hex[0] & _T('\x007f')) >= _T(' ') ? hex[0] : _T('.')); if (i0 <= i && i < i1) { rct2.left = dx; @@ -300,7 +304,7 @@ } else TextOut(hDC, dx, dy, hex, 1); - dx += hed->CharWidth; + dx += hed->CharWidth; i++; } @@ -415,6 +419,149 @@ return Index; } +static VOID +HEXEDIT_Copy(PHEXEDIT_DATA hed) +{ + PBYTE pb, buf; + UINT cb; + INT i0, i1; + HGLOBAL hGlobal; + + if (hed->SelStart < hed->SelEnd) + { + i0 = hed->SelStart; + i1 = hed->SelEnd; + } + else + { + i0 = hed->SelEnd; + i1 = hed->SelStart; + } + + cb = i1 - i0; + if (cb == 0) + return; + + hGlobal = GlobalAlloc(GHND | GMEM_SHARE, cb + sizeof(DWORD)); + if (hGlobal == NULL) + return; + + pb = GlobalLock(hGlobal); + if (pb) + { + *(PDWORD)pb = cb; + pb += sizeof(DWORD); + buf = (PBYTE) LocalLock(hed->hBuffer); + if (buf) + { + CopyMemory(pb, buf + i0, cb); + LocalUnlock(hed->hBuffer); + } + GlobalUnlock(hGlobal); + + if (OpenClipboard(hed->hWndSelf)) + { + EmptyClipboard(); + SetClipboardData(ClipboardFormatID, hGlobal); + CloseClipboard(); + } + } + else + GlobalFree(hGlobal); +} + +static VOID +HEXEDIT_Delete(PHEXEDIT_DATA hed) +{ + PBYTE buf; + INT i0, i1; + UINT bufsize; + + if (hed->SelStart < hed->SelEnd) + { + i0 = hed->SelStart; + i1 = hed->SelEnd; + } + else + { + i0 = hed->SelEnd; + i1 = hed->SelStart; + } + + if (i0 != i1) + { + bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0); + buf = (PBYTE) LocalLock(hed->hBuffer); + if (buf) + { + MoveMemory(buf + i0, buf + i1, bufsize - i1); + LocalUnlock(hed->hBuffer); + } + HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize - (i1 - i0)); + hed->InMid = FALSE; + hed->Index = hed->SelStart = hed->SelEnd = i0; + hed->CaretCol = hed->Index % hed->ColumnsPerLine; + hed->CaretLine = hed->Index / hed->ColumnsPerLine; + InvalidateRect(hed->hWndSelf, NULL, TRUE); + HEXEDIT_MoveCaret(hed, TRUE); + } +} + +static VOID +HEXEDIT_Paste(PHEXEDIT_DATA hed) +{ + HGLOBAL hGlobal; + UINT bufsize; + PBYTE pb, buf; + DWORD cb; + + HEXEDIT_Delete(hed); + bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0); + + if (OpenClipboard(hed->hWndSelf)) + { + hGlobal = GetClipboardData(ClipboardFormatID); + if (hGlobal != NULL) + { + pb = (PBYTE) GlobalLock(hGlobal); + cb = *(PDWORD) pb; + pb += sizeof(DWORD); + HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize + cb); + buf = (PBYTE) LocalLock(hed->hBuffer); + if (buf) + { + MoveMemory(buf + hed->Index + cb, buf + hed->Index, + bufsize - hed->Index); + CopyMemory(buf + hed->Index, pb, cb); + LocalUnlock(hed->hBuffer); + } + GlobalUnlock(hGlobal); + } + CloseClipboard(); + } + InvalidateRect(hed->hWndSelf, NULL, TRUE); + HEXEDIT_MoveCaret(hed, TRUE); +} + +static VOID +HEXEDIT_Cut(PHEXEDIT_DATA hed) +{ + HEXEDIT_Copy(hed); + HEXEDIT_Delete(hed); +} + +static VOID +HEXEDIT_SelectAll(PHEXEDIT_DATA hed) +{ + INT bufsize; + + bufsize = (hed->hBuffer ? (INT) LocalSize(hed->hBuffer) : 0); + hed->Index = hed->SelStart = 0; + hed->SelEnd = bufsize; + InvalidateRect(hed->hWndSelf, NULL, TRUE); + HEXEDIT_MoveCaret(hed, TRUE); +} + /*** Control specific messages ************************************************/ static LRESULT @@ -808,19 +955,18 @@ if (GetAsyncKeyState(VK_SHIFT) < 0) { - if (hed->SelOnField) + if (hed->EditingField) hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_HEXDUMP, &EditPos, &NewField); else hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_ASCIIDUMP, &EditPos, &NewField); hed->SelEnd = hed->Index; - hed->EditingField = hed->SelOnField; } else { Hit = HEXEDIT_HitRegionTest(hed, Pt); hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, Hit, &EditPos, &NewField); hed->SelStart = hed->SelEnd = hed->Index; - hed->SelOnField = hed->EditingField = NewField; + hed->EditingField = NewField; SetCapture(hed->hWndSelf); } hed->CaretCol = EditPos.x; @@ -839,7 +985,7 @@ POINT EditPos; if (GetCapture() == hed->hWndSelf) { - if (hed->SelOnField) + if (hed->EditingField) hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_HEXDUMP, &EditPos, &NewField); else hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_ASCIIDUMP, &EditPos, &NewField); @@ -860,7 +1006,7 @@ POINT EditPos; if (GetCapture() == hed->hWndSelf) { - if (hed->SelOnField) + if (hed->EditingField) hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_HEXDUMP, &EditPos, &NewField); else hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_ASCIIDUMP, &EditPos, &NewField); @@ -900,9 +1046,52 @@ switch(VkCode) { - case VK_DELETE: + case 'X': + if (GetAsyncKeyState(VK_SHIFT) >= 0 && + GetAsyncKeyState(VK_CONTROL) < 0 && hed->SelStart != hed->SelEnd) + HEXEDIT_Cut(hed); + else + return TRUE; + break; + + case 'C': + if (GetAsyncKeyState(VK_SHIFT) >= 0 && + GetAsyncKeyState(VK_CONTROL) < 0 && hed->SelStart != hed->SelEnd) + HEXEDIT_Copy(hed); + else + return TRUE; + break; + + case 'V': + if (GetAsyncKeyState(VK_SHIFT) >= 0 && GetAsyncKeyState(VK_CONTROL) < 0) + HEXEDIT_Paste(hed); + else + return TRUE; + break; + + case 'A': + if (GetAsyncKeyState(VK_SHIFT) >= 0 && GetAsyncKeyState(VK_CONTROL) < 0) + HEXEDIT_SelectAll(hed); + else + return TRUE; + break; + + case VK_INSERT: if (hed->SelStart != hed->SelEnd) { + if (GetAsyncKeyState(VK_SHIFT) >= 0 && GetAsyncKeyState(VK_CONTROL) < 0) + HEXEDIT_Copy(hed); + } + if (GetAsyncKeyState(VK_SHIFT) < 0 && GetAsyncKeyState(VK_CONTROL) >= 0) + HEXEDIT_Paste(hed); + break; + + case VK_DELETE: + if (GetAsyncKeyState(VK_SHIFT) < 0 && GetAsyncKeyState(VK_CONTROL) >= 0 && + hed->SelStart != hed->SelEnd) + HEXEDIT_Copy(hed); + if (i0 != i1) + { buf = (PBYTE) LocalLock(hed->hBuffer); if (buf) { @@ -946,7 +1135,7 @@ break; case VK_BACK: - if (hed->SelStart != hed->SelEnd) + if (i0 != i1) { buf = (PBYTE) LocalLock(hed->hBuffer); if (buf) @@ -986,6 +1175,8 @@ hed->CaretCol = hed->Index % hed->ColumnsPerLine; hed->CaretLine = hed->Index / hed->ColumnsPerLine; } + else + return TRUE; HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize - 1); hed->InMid = FALSE; } @@ -1056,6 +1247,9 @@ InvalidateRect(hed->hWndSelf, NULL, TRUE); HEXEDIT_MoveCaret(hed, TRUE); break; + + default: + return TRUE; } return FALSE; @@ -1185,6 +1379,40 @@ return 0; } +static VOID +HEXEDIT_WM_CONTEXTMENU(PHEXEDIT_DATA hed, INT x, INT y) +{ + HMENU hMenu; + RECT rc; + + if (x == -1 && y == -1) + { + GetWindowRect(hed->hWndSelf, &rc); + x = rc.left; + y = rc.top; + } + + hMenu = GetSubMenu(hPopupMenus, PM_HEXEDIT); + if (hed->SelStart == hed->SelEnd) + { + EnableMenuItem(hMenu, ID_HEXEDIT_CUT, MF_GRAYED); + EnableMenuItem(hMenu, ID_HEXEDIT_COPY, MF_GRAYED); + EnableMenuItem(hMenu, ID_HEXEDIT_PASTE, MF_GRAYED); + EnableMenuItem(hMenu, ID_HEXEDIT_DELETE, MF_GRAYED); + } + else + { + EnableMenuItem(hMenu, ID_HEXEDIT_CUT, MF_ENABLED); + EnableMenuItem(hMenu, ID_HEXEDIT_COPY, MF_ENABLED); + EnableMenuItem(hMenu, ID_HEXEDIT_PASTE, MF_ENABLED); + EnableMenuItem(hMenu, ID_HEXEDIT_DELETE, MF_ENABLED); + } + + SetForegroundWindow(hed->hWndSelf); + TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, x, y, 0, hed->hWndSelf, NULL); + PostMessage(hed->hWndSelf, WM_NULL, 0, 0); +} + INT_PTR CALLBACK HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -1291,11 +1519,32 @@ break; case WM_CONTEXTMENU: - /* FIXME: Implement Cut, Copy, Paste, Delete and Select All */ + HEXEDIT_WM_CONTEXTMENU(hed, (short)LOWORD(lParam), (short)HIWORD(lParam)); break; case WM_COMMAND: - /* FIXME: Implement Cut, Copy, Paste, Delete and Select All */ + switch(LOWORD(wParam)) + { + case ID_HEXEDIT_CUT: + HEXEDIT_Cut(hed); + break; + + case ID_HEXEDIT_COPY: + HEXEDIT_Copy(hed); + break; + + case ID_HEXEDIT_PASTE: + HEXEDIT_Paste(hed); + break; + + case ID_HEXEDIT_DELETE: + HEXEDIT_Delete(hed); + break; + + case ID_HEXEDIT_SELECT_ALL: + HEXEDIT_SelectAll(hed); + break; + } break; } Index: base/applications/regedit/lang/en-US.rc =================================================================== --- base/applications/regedit/lang/en-US.rc (revision 48222) +++ base/applications/regedit/lang/en-US.rc (working copy) @@ -160,6 +160,15 @@ MENUITEM SEPARATOR MENUITEM "&Copy Key Name", ID_EDIT_COPYKEYNAME END + POPUP "" + BEGIN + MENUITEM "C&ut", ID_HEXEDIT_CUT + MENUITEM "&Copy", ID_HEXEDIT_COPY + MENUITEM "&Paste", ID_HEXEDIT_PASTE + MENUITEM "&Delete", ID_HEXEDIT_DELETE + MENUITEM SEPARATOR + MENUITEM "Select &All", ID_HEXEDIT_SELECT_ALL + END END Index: base/applications/regedit/lang/ja-JP.rc =================================================================== --- base/applications/regedit/lang/ja-JP.rc (revision 48222) +++ base/applications/regedit/lang/ja-JP.rc (working copy) @@ -160,6 +160,15 @@ MENUITEM SEPARATOR MENUITEM "キー名のコピー(&C)", ID_EDIT_COPYKEYNAME END + POPUP "" + BEGIN + MENUITEM "切り取り(&C)", ID_HEXEDIT_CUT + MENUITEM "コピー(&C)", ID_HEXEDIT_COPY + MENUITEM "貼\り付け(&P)", ID_HEXEDIT_PASTE + MENUITEM "削除(&D)", ID_HEXEDIT_DELETE + MENUITEM SEPARATOR + MENUITEM "すべて選択(&A)", ID_HEXEDIT_SELECT_ALL + END END Index: base/applications/regedit/main.h =================================================================== --- base/applications/regedit/main.h (revision 48222) +++ base/applications/regedit/main.h (working copy) @@ -35,6 +35,7 @@ #define PM_MODIFYVALUE 0 #define PM_NEW 1 #define PM_TREECONTEXT 2 +#define PM_HEXEDIT 3 #define MAX_NEW_KEY_LEN 128 Index: base/applications/regedit/resource.h =================================================================== --- base/applications/regedit/resource.h (revision 48222) +++ base/applications/regedit/resource.h (working copy) @@ -108,6 +108,11 @@ #define ID_REGISTRY_PRINTSUBTREE 32832 #define ID_REGISTRY_PRINTERSETUP 32833 #define ID_REGISTRY_SAVESUBTREEAS 32834 +#define ID_HEXEDIT_CUT 32835 +#define ID_HEXEDIT_COPY 32836 +#define ID_HEXEDIT_PASTE 32837 +#define ID_HEXEDIT_DELETE 32838 +#define ID_HEXEDIT_SELECT_ALL 32839 #define IDS_LICENSE 32835 #define IDS_ERROR 32836 #define IDS_BAD_VALUE 32837 @@ -203,6 +208,7 @@ #define IDC_LOOKAT_DATA 2016 #define IDC_MATCHSTRING 2017 #define IDC_MATCHCASE 2018 + #define IDS_FINISHEDFIND 2019 #define ID_FAVORITES_MIN 2100 @@ -210,4 +216,5 @@ #define ID_ACCEL 3000 + #define IDC_STATIC -1 Index: base/applications/regedit/treeview.c =================================================================== --- base/applications/regedit/treeview.c (revision 48222) +++ base/applications/regedit/treeview.c (working copy) @@ -540,15 +540,16 @@ TCHAR szNewKey[128]; LPCTSTR pszKeyPath; int iIndex = 1; - HKEY hRootKey; - HKEY hKey = NULL; - HKEY hNewKey = NULL; + LONG nResult; + HKEY hRootKey = NULL, hKey = NULL, hNewKey = NULL; BOOL bSuccess = FALSE; DWORD dwDisposition; HTREEITEM hNewItem; - pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, hItem, &hRootKey); - if (RegOpenKey(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS) + pszKeyPath = GetItemPath(hwndTV, hItem, &hRootKey); + if (pszKeyPath[0] == TEXT('\0')) + hKey = hRootKey; + else if (RegOpenKey(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS) goto done; if (LoadString(hInst, IDS_NEW_KEY, szNewKeyFormat, sizeof(szNewKeyFormat) / sizeof(szNewKeyFormat[0])) <= 0) @@ -557,13 +558,20 @@ /* Need to create a new key with a unique name */ do { - _sntprintf(szNewKey, sizeof(szNewKey) / sizeof(szNewKey[0]), szNewKeyFormat, iIndex++); - RegCreateKeyEx(hKey, szNewKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hNewKey, &dwDisposition); - if (hNewKey && (dwDisposition == REG_OPENED_EXISTING_KEY)) + wsprintf(szNewKey, szNewKeyFormat, iIndex++); + nResult = RegCreateKeyEx(hKey, szNewKey, 0, NULL, 0, KEY_WRITE, NULL, &hNewKey, &dwDisposition); + if (hNewKey && dwDisposition == REG_OPENED_EXISTING_KEY) { RegCloseKey(hNewKey); hNewKey = NULL; } + else if (!hNewKey) + { + TCHAR sz[256]; + wsprintf(sz, TEXT("Cannot create new key!\n\nError Code: %d"), nResult); + MessageBox(hFrameWnd, sz, NULL, MB_ICONERROR); + goto done; + } } while(!hNewKey); @@ -578,7 +586,7 @@ bSuccess = TRUE; done: - if (hKey) + if (hKey != hRootKey && hKey) RegCloseKey(hKey); if (hNewKey) RegCloseKey(hNewKey);