|
3 | 3 | #include "ra_fwd.h" |
4 | 4 | #include "ra_utility.h" |
5 | 5 |
|
| 6 | +#include "services\IClipboard.hh" |
6 | 7 | #include "ui/EditorTheme.hh" |
7 | 8 | #include "ui/drawing/gdi/GDISurface.hh" |
8 | 9 |
|
@@ -231,6 +232,50 @@ bool MemoryViewerControlBinding::HandleNavigation(UINT nChar) |
231 | 232 | } |
232 | 233 | return true; |
233 | 234 |
|
| 235 | + case 'C': |
| 236 | + if (bControlHeld) |
| 237 | + { |
| 238 | + const auto& pEmulatorContext = ra::services::ServiceLocator::Get<ra::data::context::EmulatorContext>(); |
| 239 | + const auto iValue = pEmulatorContext.ReadMemory(m_pViewModel.GetAddress(), m_pViewModel.GetSize()); |
| 240 | + std::wstring sValue = ra::data::MemSizeFormat(iValue, m_pViewModel.GetSize(), MemFormat::Hex); |
| 241 | + ra::services::ServiceLocator::Get<ra::services::IClipboard>().SetText(ra::Widen(sValue)); |
| 242 | + } |
| 243 | + return true; |
| 244 | + |
| 245 | + case 'V': |
| 246 | + if (bControlHeld) |
| 247 | + { |
| 248 | + auto nAddress = m_pViewModel.GetAddress(); |
| 249 | + const auto& pEmulatorContext = ra::services::ServiceLocator::Get<ra::data::context::EmulatorContext>(); |
| 250 | + std::wstring sClipboardText = ra::services::ServiceLocator::Get<ra::services::IClipboard>().GetText(); |
| 251 | + auto n = m_pViewModel.GetSize(); |
| 252 | + if (sClipboardText.empty()) |
| 253 | + return false; |
| 254 | + // Check if the string is a valid hexadecimal value |
| 255 | + for (wchar_t ch : sClipboardText) |
| 256 | + if (!iswxdigit(ch)) return false; |
| 257 | + // Padding zeroes depending if shift is pressed (strict mode) or not (replace mode) |
| 258 | + if (bShiftHeld) |
| 259 | + { |
| 260 | + const auto nNibblesForSize = ra::data::MemSizeBytes(m_pViewModel.GetSize()) * 2; |
| 261 | + if (nNibblesForSize < sClipboardText.length()) |
| 262 | + sClipboardText = sClipboardText.substr(sClipboardText.length() - nNibblesForSize); |
| 263 | + else |
| 264 | + { |
| 265 | + std::wstring sPadding(nNibblesForSize - sClipboardText.length(), L'0'); |
| 266 | + sClipboardText = (sPadding + sClipboardText); |
| 267 | + } |
| 268 | + }else |
| 269 | + sClipboardText = sClipboardText.length() % 2 == 1 ? (L"0" + sClipboardText) : sClipboardText; |
| 270 | + // Writing every byte separately considerably improves stability and enables long sequences to be pasted |
| 271 | + for (int i = sClipboardText.length(); i != 0; i-=2) |
| 272 | + { |
| 273 | + std::wstring sValue = sClipboardText.substr(i - 2, 2); |
| 274 | + pEmulatorContext.WriteMemoryByte(nAddress++, std::stoi(sValue, 0, 16)); |
| 275 | + } |
| 276 | + } |
| 277 | + return true; |
| 278 | + |
234 | 279 | default: |
235 | 280 | return false; |
236 | 281 | } |
@@ -308,7 +353,9 @@ void MemoryViewerControlBinding::RenderMemViewer() |
308 | 353 |
|
309 | 354 | const auto& pRenderImage = m_pViewModel.GetRenderImage(); |
310 | 355 | const auto& pEditorTheme = ra::services::ServiceLocator::Get<ra::ui::EditorTheme>(); |
311 | | - HBRUSH hBackground = CreateSolidBrush(RGB(pEditorTheme.ColorBackground().Channel.R, pEditorTheme.ColorBackground().Channel.G, pEditorTheme.ColorBackground().Channel.B)); |
| 356 | + HBRUSH hBackground = CreateSolidBrush(RGB(pEditorTheme.ColorBackground().Channel.R, |
| 357 | + pEditorTheme.ColorBackground().Channel.G, |
| 358 | + pEditorTheme.ColorBackground().Channel.B)); |
312 | 359 |
|
313 | 360 | // left margin |
314 | 361 | RECT rcFill{ rcClient.left, rcClient.top, rcClient.left + MEMVIEW_MARGIN, rcClient.bottom - 1 }; |
|
0 commit comments