Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhexedit.c
Go to the documentation of this file.
00001 /* 00002 * Hex editor control 00003 * 00004 * Copyright (C) 2004 Thomas Weidenmueller <w3seek@reactos.com> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include <regedit.h> 00022 typedef struct 00023 { 00024 HWND hWndSelf; 00025 HWND hWndParent; 00026 HLOCAL hBuffer; 00027 DWORD style; 00028 DWORD MaxBuffer; 00029 INT ColumnsPerLine; 00030 INT nLines; 00031 INT nVisibleLinesComplete; 00032 INT nVisibleLines; 00033 INT Index; 00034 INT LineHeight; 00035 INT CharWidth; 00036 HFONT hFont; 00037 BOOL SbVisible; 00038 00039 INT LeftMargin; 00040 INT AddressSpacing; 00041 INT SplitSpacing; 00042 00043 BOOL EditingField; 00044 INT CaretCol; 00045 INT CaretLine; 00046 BOOL InMid; 00047 00048 INT SelStart; 00049 INT SelEnd; 00050 } HEXEDIT_DATA, *PHEXEDIT_DATA; 00051 00052 static const TCHAR ClipboardFormatName[] = TEXT("RegEdit_HexData"); 00053 static UINT ClipboardFormatID = 0; 00054 00055 /* hit test codes */ 00056 #define HEHT_LEFTMARGIN (0x1) 00057 #define HEHT_ADDRESS (0x2) 00058 #define HEHT_ADDRESSSPACING (0x3) 00059 #define HEHT_HEXDUMP (0x4) 00060 #define HEHT_HEXDUMPSPACING (0x5) 00061 #define HEHT_ASCIIDUMP (0x6) 00062 #define HEHT_RIGHTMARGIN (0x7) 00063 00064 INT_PTR CALLBACK HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 00065 00066 ATOM 00067 WINAPI 00068 RegisterHexEditorClass(HINSTANCE hInstance) 00069 { 00070 WNDCLASSEX WndClass; 00071 00072 ClipboardFormatID = RegisterClipboardFormat(ClipboardFormatName); 00073 00074 ZeroMemory(&WndClass, sizeof(WNDCLASSEX)); 00075 WndClass.cbSize = sizeof(WNDCLASSEX); 00076 WndClass.style = CS_DBLCLKS; 00077 WndClass.lpfnWndProc = (WNDPROC)HexEditWndProc; 00078 WndClass.cbWndExtra = sizeof(PHEXEDIT_DATA); 00079 WndClass.hInstance = hInstance; 00080 WndClass.hCursor = LoadCursor(0, IDC_IBEAM); 00081 WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 00082 WndClass.lpszClassName = HEX_EDIT_CLASS_NAME; 00083 00084 return RegisterClassEx(&WndClass); 00085 } 00086 00087 BOOL 00088 WINAPI 00089 UnregisterHexEditorClass(HINSTANCE hInstance) 00090 { 00091 return UnregisterClass(HEX_EDIT_CLASS_NAME, hInstance); 00092 } 00093 00094 /*** Helper functions *********************************************************/ 00095 00096 static VOID 00097 HEXEDIT_MoveCaret(PHEXEDIT_DATA hed, BOOL Scroll) 00098 { 00099 SCROLLINFO si; 00100 00101 si.cbSize = sizeof(SCROLLINFO); 00102 si.fMask = SIF_POS; 00103 GetScrollInfo(hed->hWndSelf, SB_VERT, &si); 00104 00105 if(Scroll) 00106 { 00107 if(si.nPos > hed->CaretLine) 00108 { 00109 si.nPos = hed->CaretLine; 00110 SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE); 00111 GetScrollInfo(hed->hWndSelf, SB_VERT, &si); 00112 InvalidateRect(hed->hWndSelf, NULL, TRUE); 00113 } 00114 else if(hed->CaretLine >= (hed->nVisibleLinesComplete + si.nPos)) 00115 { 00116 si.nPos = hed->CaretLine - hed->nVisibleLinesComplete + 1; 00117 SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE); 00118 GetScrollInfo(hed->hWndSelf, SB_VERT, &si); 00119 InvalidateRect(hed->hWndSelf, NULL, TRUE); 00120 } 00121 } 00122 00123 if(hed->EditingField) 00124 SetCaretPos(hed->LeftMargin + ((4 + hed->AddressSpacing + (3 * hed->CaretCol) + hed->InMid * 2) * hed->CharWidth) - 1, (hed->CaretLine - si.nPos) * hed->LineHeight); 00125 else 00126 SetCaretPos(hed->LeftMargin + ((4 + hed->AddressSpacing + hed->SplitSpacing + (3 * hed->ColumnsPerLine) + hed->CaretCol) * hed->CharWidth) - 2, (hed->CaretLine - si.nPos) * hed->LineHeight); 00127 } 00128 00129 static VOID 00130 HEXEDIT_Update(PHEXEDIT_DATA hed) 00131 { 00132 SCROLLINFO si; 00133 RECT rcClient; 00134 BOOL SbVisible; 00135 INT bufsize, cvislines; 00136 00137 GetClientRect(hed->hWndSelf, &rcClient); 00138 hed->style = GetWindowLongPtr(hed->hWndSelf, GWL_STYLE); 00139 00140 bufsize = (hed->hBuffer ? (INT) LocalSize(hed->hBuffer) : 0); 00141 hed->nLines = max(bufsize / hed->ColumnsPerLine, 1); 00142 if(bufsize > hed->ColumnsPerLine && (bufsize % hed->ColumnsPerLine) > 0) 00143 { 00144 hed->nLines++; 00145 } 00146 00147 if(hed->LineHeight > 0) 00148 { 00149 hed->nVisibleLinesComplete = cvislines = rcClient.bottom / hed->LineHeight; 00150 hed->nVisibleLines = hed->nVisibleLinesComplete; 00151 if(rcClient.bottom % hed->LineHeight) 00152 { 00153 hed->nVisibleLines++; 00154 } 00155 } 00156 else 00157 { 00158 hed->nVisibleLines = cvislines = 0; 00159 } 00160 00161 SbVisible = bufsize > 0 && cvislines < hed->nLines; 00162 ShowScrollBar(hed->hWndSelf, SB_VERT, SbVisible); 00163 00164 /* update scrollbar */ 00165 si.cbSize = sizeof(SCROLLINFO); 00166 si.fMask = SIF_RANGE | SIF_PAGE; 00167 si.nMin = 0; 00168 si.nMax = ((bufsize > 0) ? hed->nLines - 1 : 0); 00169 si.nPage = ((hed->LineHeight > 0) ? rcClient.bottom / hed->LineHeight : 0); 00170 SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE); 00171 00172 if(IsWindowVisible(hed->hWndSelf) && SbVisible != hed->SbVisible) 00173 { 00174 InvalidateRect(hed->hWndSelf, NULL, TRUE); 00175 } 00176 00177 hed->SbVisible = SbVisible; 00178 } 00179 00180 static HFONT 00181 HEXEDIT_GetFixedFont(VOID) 00182 { 00183 LOGFONT lf; 00184 GetObject(GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT), &lf); 00185 return CreateFontIndirect(&lf); 00186 } 00187 00188 static VOID 00189 HEXEDIT_PaintLines(PHEXEDIT_DATA hed, HDC hDC, DWORD ScrollPos, DWORD First, DWORD Last, RECT *rc) 00190 { 00191 DWORD dx, dy, linestart; 00192 INT i, isave, i0, i1, x; 00193 PBYTE buf, current, end, line; 00194 size_t bufsize; 00195 TCHAR hex[3], addr[17]; 00196 RECT rct, rct2; 00197 00198 FillRect(hDC, rc, (HBRUSH)(COLOR_WINDOW + 1)); 00199 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); 00200 00201 if (hed->SelStart < hed->SelEnd) 00202 { 00203 i0 = hed->SelStart; 00204 i1 = hed->SelEnd; 00205 } 00206 else 00207 { 00208 i0 = hed->SelEnd; 00209 i1 = hed->SelStart; 00210 } 00211 00212 if(hed->hBuffer) 00213 { 00214 bufsize = LocalSize(hed->hBuffer); 00215 buf = LocalLock(hed->hBuffer); 00216 } 00217 else 00218 { 00219 buf = NULL; 00220 bufsize = 0; 00221 00222 if(ScrollPos + First == 0) 00223 { 00224 /* draw address */ 00225 wsprintf(addr, TEXT("%04X"), 0); 00226 TextOut(hDC, hed->LeftMargin, First * hed->LineHeight, addr, 4); 00227 } 00228 } 00229 00230 if(buf) 00231 { 00232 end = buf + bufsize; 00233 dy = First * hed->LineHeight; 00234 linestart = (ScrollPos + First) * hed->ColumnsPerLine; 00235 i = linestart; 00236 current = buf + linestart; 00237 Last = min(hed->nLines - ScrollPos, Last); 00238 00239 SetBkMode(hDC, TRANSPARENT); 00240 while(First <= Last && current < end) 00241 { 00242 DWORD dh; 00243 00244 dx = hed->LeftMargin; 00245 00246 /* draw address */ 00247 wsprintf(addr, TEXT("%04lX"), linestart); 00248 TextOut(hDC, dx, dy, addr, 4); 00249 00250 dx += ((4 + hed->AddressSpacing) * hed->CharWidth); 00251 dh = (3 * hed->CharWidth); 00252 00253 rct.left = dx; 00254 rct.top = dy; 00255 rct.right = rct.left + dh; 00256 rct.bottom = dy + hed->LineHeight; 00257 00258 /* draw hex map */ 00259 dx += (hed->CharWidth / 2); 00260 line = current; 00261 isave = i; 00262 for(x = 0; x < hed->ColumnsPerLine && current < end; x++) 00263 { 00264 rct.left += dh; 00265 rct.right += dh; 00266 00267 wsprintf(hex, TEXT("%02X"), *(current++)); 00268 if (i0 <= i && i < i1) 00269 { 00270 rct2.left = dx; 00271 rct2.top = dy; 00272 rct2.right = dx + hed->CharWidth * 2 + 1; 00273 rct2.bottom = dy + hed->LineHeight; 00274 InflateRect(&rct2, hed->CharWidth / 2, 0); 00275 FillRect(hDC, &rct2, (HBRUSH)(COLOR_HIGHLIGHT + 1)); 00276 SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); 00277 ExtTextOut(hDC, dx, dy, 0, &rct, hex, 2, NULL); 00278 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); 00279 } 00280 else 00281 ExtTextOut(hDC, dx, dy, ETO_OPAQUE, &rct, hex, 2, NULL); 00282 dx += dh; 00283 i++; 00284 } 00285 00286 /* draw ascii map */ 00287 dx = ((4 + hed->AddressSpacing + hed->SplitSpacing + (hed->ColumnsPerLine * 3)) * hed->CharWidth); 00288 current = line; 00289 i = isave; 00290 for(x = 0; x < hed->ColumnsPerLine && current < end; x++) 00291 { 00292 wsprintf(hex, _T("%C"), *(current++)); 00293 hex[0] = ((hex[0] & _T('\x007f')) >= _T(' ') ? hex[0] : _T('.')); 00294 if (i0 <= i && i < i1) 00295 { 00296 rct2.left = dx; 00297 rct2.top = dy; 00298 rct2.right = dx + hed->CharWidth; 00299 rct2.bottom = dy + hed->LineHeight; 00300 FillRect(hDC, &rct2, (HBRUSH)(COLOR_HIGHLIGHT + 1)); 00301 SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); 00302 TextOut(hDC, dx, dy, hex, 1); 00303 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); 00304 } 00305 else 00306 TextOut(hDC, dx, dy, hex, 1); 00307 dx += hed->CharWidth; 00308 i++; 00309 } 00310 00311 dy += hed->LineHeight; 00312 linestart += hed->ColumnsPerLine; 00313 First++; 00314 } 00315 } 00316 00317 LocalUnlock(hed->hBuffer); 00318 } 00319 00320 static DWORD 00321 HEXEDIT_HitRegionTest(PHEXEDIT_DATA hed, POINTS pt) 00322 { 00323 int d; 00324 00325 if(pt.x <= hed->LeftMargin) 00326 { 00327 return HEHT_LEFTMARGIN; 00328 } 00329 00330 pt.x -= hed->LeftMargin; 00331 d = (4 * hed->CharWidth); 00332 if(pt.x <= d) 00333 { 00334 return HEHT_ADDRESS; 00335 } 00336 00337 pt.x -= d; 00338 d = (hed->AddressSpacing * hed->CharWidth); 00339 if(pt.x <= d) 00340 { 00341 return HEHT_ADDRESSSPACING; 00342 } 00343 00344 pt.x -= d; 00345 d = ((3 * hed->ColumnsPerLine + 1) * hed->CharWidth); 00346 if(pt.x <= d) 00347 { 00348 return HEHT_HEXDUMP; 00349 } 00350 00351 pt.x -= d; 00352 d = ((hed->SplitSpacing - 1) * hed->CharWidth); 00353 if(pt.x <= d) 00354 { 00355 return HEHT_HEXDUMPSPACING; 00356 } 00357 00358 pt.x -= d; 00359 d = (hed->ColumnsPerLine * hed->CharWidth); 00360 if(pt.x <= d) 00361 { 00362 return HEHT_ASCIIDUMP; 00363 } 00364 00365 return HEHT_RIGHTMARGIN; 00366 } 00367 00368 static DWORD 00369 HEXEDIT_IndexFromPoint(PHEXEDIT_DATA hed, POINTS pt, DWORD Hit, POINT *EditPos, BOOL *EditField) 00370 { 00371 SCROLLINFO si; 00372 DWORD Index, bufsize; 00373 00374 si.cbSize = sizeof(SCROLLINFO); 00375 si.fMask = SIF_POS; 00376 GetScrollInfo(hed->hWndSelf, SB_VERT, &si); 00377 00378 EditPos->x = 0; 00379 00380 if(hed->LineHeight > 0) 00381 { 00382 EditPos->y = min(si.nPos + (pt.y / hed->LineHeight), hed->nLines - 1); 00383 } 00384 else 00385 { 00386 EditPos->y = si.nPos; 00387 } 00388 00389 switch(Hit) 00390 { 00391 case HEHT_LEFTMARGIN: 00392 case HEHT_ADDRESS: 00393 case HEHT_ADDRESSSPACING: 00394 case HEHT_HEXDUMP: 00395 pt.x -= (SHORT) hed->LeftMargin + ((4 + hed->AddressSpacing) * hed->CharWidth); 00396 *EditField = TRUE; 00397 break; 00398 00399 default: 00400 pt.x -= hed->LeftMargin + ((4 + hed->AddressSpacing + hed->SplitSpacing + (3 * hed->ColumnsPerLine)) * hed->CharWidth); 00401 *EditField = FALSE; 00402 break; 00403 } 00404 00405 if(pt.x > 0) 00406 { 00407 INT BlockWidth = (*EditField ? hed->CharWidth * 3 : hed->CharWidth); 00408 EditPos->x = min(hed->ColumnsPerLine, (pt.x + BlockWidth / 2) / BlockWidth); 00409 } 00410 00411 bufsize = (hed->hBuffer ? (DWORD) LocalSize(hed->hBuffer) : 0); 00412 Index = (EditPos->y * hed->ColumnsPerLine) + EditPos->x; 00413 if(Index > bufsize) 00414 { 00415 INT tmp = bufsize % hed->ColumnsPerLine; 00416 Index = bufsize; 00417 EditPos->x = (tmp == 0 ? hed->ColumnsPerLine : tmp); 00418 } 00419 return Index; 00420 } 00421 00422 static VOID 00423 HEXEDIT_Copy(PHEXEDIT_DATA hed) 00424 { 00425 PBYTE pb, buf; 00426 UINT cb; 00427 INT i0, i1; 00428 HGLOBAL hGlobal; 00429 00430 if (hed->SelStart < hed->SelEnd) 00431 { 00432 i0 = hed->SelStart; 00433 i1 = hed->SelEnd; 00434 } 00435 else 00436 { 00437 i0 = hed->SelEnd; 00438 i1 = hed->SelStart; 00439 } 00440 00441 cb = i1 - i0; 00442 if (cb == 0) 00443 return; 00444 00445 hGlobal = GlobalAlloc(GHND | GMEM_SHARE, cb + sizeof(DWORD)); 00446 if (hGlobal == NULL) 00447 return; 00448 00449 pb = GlobalLock(hGlobal); 00450 if (pb) 00451 { 00452 *(PDWORD)pb = cb; 00453 pb += sizeof(DWORD); 00454 buf = (PBYTE) LocalLock(hed->hBuffer); 00455 if (buf) 00456 { 00457 CopyMemory(pb, buf + i0, cb); 00458 LocalUnlock(hed->hBuffer); 00459 } 00460 GlobalUnlock(hGlobal); 00461 00462 if (OpenClipboard(hed->hWndSelf)) 00463 { 00464 EmptyClipboard(); 00465 SetClipboardData(ClipboardFormatID, hGlobal); 00466 CloseClipboard(); 00467 } 00468 } 00469 else 00470 GlobalFree(hGlobal); 00471 } 00472 00473 static VOID 00474 HEXEDIT_Delete(PHEXEDIT_DATA hed) 00475 { 00476 PBYTE buf; 00477 INT i0, i1; 00478 UINT bufsize; 00479 00480 if (hed->SelStart < hed->SelEnd) 00481 { 00482 i0 = hed->SelStart; 00483 i1 = hed->SelEnd; 00484 } 00485 else 00486 { 00487 i0 = hed->SelEnd; 00488 i1 = hed->SelStart; 00489 } 00490 00491 if (i0 != i1) 00492 { 00493 bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0); 00494 buf = (PBYTE) LocalLock(hed->hBuffer); 00495 if (buf) 00496 { 00497 MoveMemory(buf + i0, buf + i1, bufsize - i1); 00498 LocalUnlock(hed->hBuffer); 00499 } 00500 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize - (i1 - i0)); 00501 hed->InMid = FALSE; 00502 hed->Index = hed->SelStart = hed->SelEnd = i0; 00503 hed->CaretCol = hed->Index % hed->ColumnsPerLine; 00504 hed->CaretLine = hed->Index / hed->ColumnsPerLine; 00505 InvalidateRect(hed->hWndSelf, NULL, TRUE); 00506 HEXEDIT_MoveCaret(hed, TRUE); 00507 } 00508 } 00509 00510 static VOID 00511 HEXEDIT_Paste(PHEXEDIT_DATA hed) 00512 { 00513 HGLOBAL hGlobal; 00514 UINT bufsize; 00515 PBYTE pb, buf; 00516 DWORD cb; 00517 00518 HEXEDIT_Delete(hed); 00519 bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0); 00520 00521 if (OpenClipboard(hed->hWndSelf)) 00522 { 00523 hGlobal = GetClipboardData(ClipboardFormatID); 00524 if (hGlobal != NULL) 00525 { 00526 pb = (PBYTE) GlobalLock(hGlobal); 00527 cb = *(PDWORD) pb; 00528 pb += sizeof(DWORD); 00529 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize + cb); 00530 buf = (PBYTE) LocalLock(hed->hBuffer); 00531 if (buf) 00532 { 00533 MoveMemory(buf + hed->Index + cb, buf + hed->Index, 00534 bufsize - hed->Index); 00535 CopyMemory(buf + hed->Index, pb, cb); 00536 LocalUnlock(hed->hBuffer); 00537 } 00538 GlobalUnlock(hGlobal); 00539 } 00540 CloseClipboard(); 00541 } 00542 InvalidateRect(hed->hWndSelf, NULL, TRUE); 00543 HEXEDIT_MoveCaret(hed, TRUE); 00544 } 00545 00546 static VOID 00547 HEXEDIT_Cut(PHEXEDIT_DATA hed) 00548 { 00549 HEXEDIT_Copy(hed); 00550 HEXEDIT_Delete(hed); 00551 } 00552 00553 static VOID 00554 HEXEDIT_SelectAll(PHEXEDIT_DATA hed) 00555 { 00556 INT bufsize; 00557 00558 bufsize = (hed->hBuffer ? (INT) LocalSize(hed->hBuffer) : 0); 00559 hed->Index = hed->SelStart = 0; 00560 hed->SelEnd = bufsize; 00561 InvalidateRect(hed->hWndSelf, NULL, TRUE); 00562 HEXEDIT_MoveCaret(hed, TRUE); 00563 } 00564 00565 /*** Control specific messages ************************************************/ 00566 00567 static LRESULT 00568 HEXEDIT_HEM_LOADBUFFER(PHEXEDIT_DATA hed, PVOID Buffer, DWORD Size) 00569 { 00570 if(Buffer != NULL && Size > 0) 00571 { 00572 LPVOID buf; 00573 00574 if(hed->MaxBuffer > 0 && Size > hed->MaxBuffer) 00575 { 00576 Size = hed->MaxBuffer; 00577 } 00578 00579 if(hed->hBuffer) 00580 { 00581 if(Size > 0) 00582 { 00583 if(LocalSize(hed->hBuffer) != Size) 00584 { 00585 hed->hBuffer = LocalReAlloc(hed->hBuffer, Size, LMEM_MOVEABLE | LMEM_ZEROINIT); 00586 } 00587 } 00588 else 00589 { 00590 hed->hBuffer = LocalFree(hed->hBuffer); 00591 hed->Index = 0; 00592 HEXEDIT_Update(hed); 00593 00594 return 0; 00595 } 00596 } 00597 else if(Size > 0) 00598 { 00599 hed->hBuffer = LocalAlloc(LHND, Size); 00600 } 00601 00602 if(Size > 0) 00603 { 00604 buf = LocalLock(hed->hBuffer); 00605 if(buf) 00606 { 00607 memcpy(buf, Buffer, Size); 00608 } 00609 else 00610 Size = 0; 00611 LocalUnlock(hed->hBuffer); 00612 } 00613 00614 hed->Index = 0; 00615 HEXEDIT_Update(hed); 00616 return Size; 00617 } 00618 else if(hed->hBuffer) 00619 { 00620 hed->Index = 0; 00621 hed->hBuffer = LocalFree(hed->hBuffer); 00622 HEXEDIT_Update(hed); 00623 } 00624 00625 return 0; 00626 } 00627 00628 static LRESULT 00629 HEXEDIT_HEM_COPYBUFFER(PHEXEDIT_DATA hed, PVOID Buffer, DWORD Size) 00630 { 00631 size_t nCpy; 00632 00633 if(!hed->hBuffer) 00634 { 00635 return 0; 00636 } 00637 00638 if(Buffer != NULL && Size > 0) 00639 { 00640 nCpy = min(Size, LocalSize(hed->hBuffer)); 00641 if(nCpy > 0) 00642 { 00643 PVOID buf; 00644 00645 buf = LocalLock(hed->hBuffer); 00646 if(buf) 00647 { 00648 memcpy(Buffer, buf, nCpy); 00649 } 00650 else 00651 nCpy = 0; 00652 LocalUnlock(hed->hBuffer); 00653 } 00654 return nCpy; 00655 } 00656 00657 return (LRESULT)LocalSize(hed->hBuffer); 00658 } 00659 00660 static LRESULT 00661 HEXEDIT_HEM_SETMAXBUFFERSIZE(PHEXEDIT_DATA hed, DWORD nMaxSize) 00662 { 00663 hed->MaxBuffer = nMaxSize; 00664 if (hed->MaxBuffer == 0) 00665 { 00666 hed->hBuffer = LocalFree(hed->hBuffer); 00667 return 0; 00668 } 00669 if (hed->hBuffer) 00670 hed->hBuffer = LocalReAlloc(hed->hBuffer, hed->MaxBuffer, LMEM_MOVEABLE); 00671 else 00672 hed->hBuffer = LocalAlloc(LMEM_MOVEABLE, hed->MaxBuffer); 00673 HEXEDIT_Update(hed); 00674 return 0; 00675 } 00676 00677 /*** Message Proc *************************************************************/ 00678 00679 static LRESULT 00680 HEXEDIT_WM_NCCREATE(HWND hWnd, CREATESTRUCT *cs) 00681 { 00682 PHEXEDIT_DATA hed; 00683 00684 if(!(hed = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HEXEDIT_DATA)))) 00685 { 00686 return FALSE; 00687 } 00688 00689 hed->hWndSelf = hWnd; 00690 hed->hWndParent = cs->hwndParent; 00691 hed->style = cs->style; 00692 00693 hed->ColumnsPerLine = 8; 00694 hed->LeftMargin = 2; 00695 hed->AddressSpacing = 2; 00696 hed->SplitSpacing = 2; 00697 hed->EditingField = TRUE; /* in hexdump field */ 00698 00699 SetWindowLongPtr(hWnd, 0, (DWORD_PTR)hed); 00700 HEXEDIT_Update(hed); 00701 00702 return TRUE; 00703 } 00704 00705 static LRESULT 00706 HEXEDIT_WM_NCDESTROY(PHEXEDIT_DATA hed) 00707 { 00708 if(hed->hBuffer) 00709 { 00710 //while(LocalUnlock(hed->hBuffer)); 00711 LocalFree(hed->hBuffer); 00712 } 00713 00714 if(hed->hFont) 00715 { 00716 DeleteObject(hed->hFont); 00717 } 00718 00719 SetWindowLongPtr(hed->hWndSelf, 0, (DWORD_PTR)0); 00720 HeapFree(GetProcessHeap(), 0, hed); 00721 00722 return 0; 00723 } 00724 00725 static LRESULT 00726 HEXEDIT_WM_CREATE(PHEXEDIT_DATA hed) 00727 { 00728 UNREFERENCED_PARAMETER(hed); 00729 return 1; 00730 } 00731 00732 static LRESULT 00733 HEXEDIT_WM_SETFOCUS(PHEXEDIT_DATA hed) 00734 { 00735 CreateCaret(hed->hWndSelf, 0, 1, hed->LineHeight); 00736 HEXEDIT_MoveCaret(hed, FALSE); 00737 ShowCaret(hed->hWndSelf); 00738 return 0; 00739 } 00740 00741 static LRESULT 00742 HEXEDIT_WM_KILLFOCUS(PHEXEDIT_DATA hed) 00743 { 00744 UNREFERENCED_PARAMETER(hed); 00745 DestroyCaret(); 00746 return 0; 00747 } 00748 00749 static LRESULT 00750 HEXEDIT_WM_VSCROLL(PHEXEDIT_DATA hed, WORD ThumbPosition, WORD SbCmd) 00751 { 00752 int ScrollY; 00753 SCROLLINFO si; 00754 00755 UNREFERENCED_PARAMETER(ThumbPosition); 00756 00757 ZeroMemory(&si, sizeof(SCROLLINFO)); 00758 si.cbSize = sizeof(SCROLLINFO); 00759 si.fMask = SIF_ALL; 00760 GetScrollInfo(hed->hWndSelf, SB_VERT, &si); 00761 00762 ScrollY = si.nPos; 00763 switch(SbCmd) 00764 { 00765 case SB_TOP: 00766 si.nPos = si.nMin; 00767 break; 00768 00769 case SB_BOTTOM: 00770 si.nPos = si.nMax; 00771 break; 00772 00773 case SB_LINEUP: 00774 si.nPos--; 00775 break; 00776 00777 case SB_LINEDOWN: 00778 si.nPos++; 00779 break; 00780 00781 case SB_PAGEUP: 00782 si.nPos -= si.nPage; 00783 break; 00784 00785 case SB_PAGEDOWN: 00786 si.nPos += si.nPage; 00787 break; 00788 00789 case SB_THUMBTRACK: 00790 si.nPos = si.nTrackPos; 00791 break; 00792 } 00793 00794 si.fMask = SIF_POS; 00795 SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE); 00796 GetScrollInfo(hed->hWndSelf, SB_VERT, &si); 00797 00798 if(si.nPos != ScrollY) 00799 { 00800 ScrollWindow(hed->hWndSelf, 0, (ScrollY - si.nPos) * hed->LineHeight, NULL, NULL); 00801 UpdateWindow(hed->hWndSelf); 00802 } 00803 00804 return 0; 00805 } 00806 00807 static LRESULT 00808 HEXEDIT_WM_SETFONT(PHEXEDIT_DATA hed, HFONT hFont, BOOL bRedraw) 00809 { 00810 HDC hDC; 00811 TEXTMETRIC tm; 00812 HFONT hOldFont = 0; 00813 00814 if(hFont == 0) 00815 { 00816 hFont = HEXEDIT_GetFixedFont(); 00817 } 00818 00819 hed->hFont = hFont; 00820 hDC = GetDC(hed->hWndSelf); 00821 if(hFont) 00822 { 00823 hOldFont = SelectObject(hDC, hFont); 00824 } 00825 GetTextMetrics(hDC, &tm); 00826 hed->LineHeight = tm.tmHeight; 00827 hed->CharWidth = tm.tmAveCharWidth; 00828 if(hOldFont) 00829 { 00830 SelectObject(hDC, hOldFont); 00831 } 00832 ReleaseDC(hed->hWndSelf, hDC); 00833 00834 if(bRedraw) 00835 { 00836 InvalidateRect(hed->hWndSelf, NULL, TRUE); 00837 } 00838 00839 return 0; 00840 } 00841 00842 static LRESULT 00843 HEXEDIT_WM_GETFONT(PHEXEDIT_DATA hed) 00844 { 00845 return (LRESULT)hed->hFont; 00846 } 00847 00848 static LRESULT 00849 HEXEDIT_WM_PAINT(PHEXEDIT_DATA hed) 00850 { 00851 PAINTSTRUCT ps; 00852 SCROLLINFO si; 00853 RECT rc; 00854 HBITMAP hbmp, hbmpold; 00855 INT nLines, nFirst; 00856 HFONT hOldFont; 00857 HDC hTempDC; 00858 DWORD height; 00859 00860 if(GetUpdateRect(hed->hWndSelf, &rc, FALSE) && (hed->LineHeight > 0)) 00861 { 00862 ZeroMemory(&si, sizeof(SCROLLINFO)); 00863 si.cbSize = sizeof(SCROLLINFO); 00864 si.fMask = SIF_POS; 00865 GetScrollInfo(hed->hWndSelf, SB_VERT, &si); 00866 00867 height = (rc.bottom - rc.top); 00868 nLines = height / hed->LineHeight; 00869 if((height % hed->LineHeight) > 0) 00870 { 00871 nLines++; 00872 } 00873 if(nLines > hed->nLines - si.nPos) 00874 { 00875 nLines = hed->nLines - si.nPos; 00876 } 00877 nFirst = rc.top / hed->LineHeight; 00878 00879 BeginPaint(hed->hWndSelf, &ps); 00880 if(!(hTempDC = CreateCompatibleDC(ps.hdc))) 00881 { 00882 FillRect(ps.hdc, &rc, (HBRUSH)(COLOR_WINDOW + 1)); 00883 goto epaint; 00884 } 00885 if(!(hbmp = CreateCompatibleBitmap(ps.hdc, ps.rcPaint.right, ps.rcPaint.bottom))) 00886 { 00887 FillRect(ps.hdc, &rc, (HBRUSH)(COLOR_WINDOW + 1)); 00888 DeleteDC(hTempDC); 00889 goto epaint; 00890 } 00891 hbmpold = SelectObject(hTempDC, hbmp); 00892 hOldFont = SelectObject(hTempDC, hed->hFont); 00893 HEXEDIT_PaintLines(hed, hTempDC, si.nPos, nFirst, nFirst + nLines, &ps.rcPaint); 00894 BitBlt(ps.hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hTempDC, rc.left, rc.top, SRCCOPY); 00895 SelectObject(hTempDC, hOldFont); 00896 SelectObject(hTempDC, hbmpold); 00897 00898 DeleteObject(hbmp); 00899 DeleteDC(hTempDC); 00900 00901 epaint: 00902 EndPaint(hed->hWndSelf, &ps); 00903 } 00904 00905 return 0; 00906 } 00907 00908 static LRESULT 00909 HEXEDIT_WM_MOUSEWHEEL(PHEXEDIT_DATA hed, int cyMoveLines, WORD ButtonsDown, LPPOINTS MousePos) 00910 { 00911 SCROLLINFO si; 00912 int ScrollY; 00913 00914 UNREFERENCED_PARAMETER(ButtonsDown); 00915 UNREFERENCED_PARAMETER(MousePos); 00916 00917 SetFocus(hed->hWndSelf); 00918 00919 si.cbSize = sizeof(SCROLLINFO); 00920 si.fMask = SIF_ALL; 00921 GetScrollInfo(hed->hWndSelf, SB_VERT, &si); 00922 00923 ScrollY = si.nPos; 00924 00925 si.fMask = SIF_POS; 00926 si.nPos += cyMoveLines; 00927 SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE); 00928 00929 GetScrollInfo(hed->hWndSelf, SB_VERT, &si); 00930 if(si.nPos != ScrollY) 00931 { 00932 ScrollWindow(hed->hWndSelf, 0, (ScrollY - si.nPos) * hed->LineHeight, NULL, NULL); 00933 UpdateWindow(hed->hWndSelf); 00934 } 00935 00936 return 0; 00937 } 00938 00939 static LRESULT 00940 HEXEDIT_WM_GETDLGCODE(LPMSG Msg) 00941 { 00942 UNREFERENCED_PARAMETER(Msg); 00943 return DLGC_WANTARROWS | DLGC_WANTCHARS; 00944 } 00945 00946 static LRESULT 00947 HEXEDIT_WM_LBUTTONDOWN(PHEXEDIT_DATA hed, INT Buttons, POINTS Pt) 00948 { 00949 BOOL NewField; 00950 POINT EditPos; 00951 DWORD Hit; 00952 00953 UNREFERENCED_PARAMETER(Buttons); 00954 SetFocus(hed->hWndSelf); 00955 00956 if (GetAsyncKeyState(VK_SHIFT) < 0) 00957 { 00958 if (hed->EditingField) 00959 hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_HEXDUMP, &EditPos, &NewField); 00960 else 00961 hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_ASCIIDUMP, &EditPos, &NewField); 00962 hed->SelEnd = hed->Index; 00963 } 00964 else 00965 { 00966 Hit = HEXEDIT_HitRegionTest(hed, Pt); 00967 hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, Hit, &EditPos, &NewField); 00968 hed->SelStart = hed->SelEnd = hed->Index; 00969 hed->EditingField = NewField; 00970 SetCapture(hed->hWndSelf); 00971 } 00972 hed->CaretCol = EditPos.x; 00973 hed->CaretLine = EditPos.y; 00974 hed->InMid = FALSE; 00975 InvalidateRect(hed->hWndSelf, NULL, FALSE); 00976 HEXEDIT_MoveCaret(hed, TRUE); 00977 00978 return 0; 00979 } 00980 00981 static LRESULT 00982 HEXEDIT_WM_LBUTTONUP(PHEXEDIT_DATA hed, INT Buttons, POINTS Pt) 00983 { 00984 BOOL NewField; 00985 POINT EditPos; 00986 if (GetCapture() == hed->hWndSelf) 00987 { 00988 if (hed->EditingField) 00989 hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_HEXDUMP, &EditPos, &NewField); 00990 else 00991 hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_ASCIIDUMP, &EditPos, &NewField); 00992 hed->CaretCol = EditPos.x; 00993 hed->CaretLine = EditPos.y; 00994 hed->SelEnd = hed->Index; 00995 ReleaseCapture(); 00996 InvalidateRect(hed->hWndSelf, NULL, FALSE); 00997 HEXEDIT_MoveCaret(hed, TRUE); 00998 } 00999 return 0; 01000 } 01001 01002 static LRESULT 01003 HEXEDIT_WM_MOUSEMOVE(PHEXEDIT_DATA hed, INT Buttons, POINTS Pt) 01004 { 01005 BOOL NewField; 01006 POINT EditPos; 01007 if (GetCapture() == hed->hWndSelf) 01008 { 01009 if (hed->EditingField) 01010 hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_HEXDUMP, &EditPos, &NewField); 01011 else 01012 hed->Index = HEXEDIT_IndexFromPoint(hed, Pt, HEHT_ASCIIDUMP, &EditPos, &NewField); 01013 hed->CaretCol = EditPos.x; 01014 hed->CaretLine = EditPos.y; 01015 hed->SelEnd = hed->Index; 01016 InvalidateRect(hed->hWndSelf, NULL, FALSE); 01017 HEXEDIT_MoveCaret(hed, TRUE); 01018 } 01019 return 0; 01020 } 01021 01022 static BOOL 01023 HEXEDIT_WM_KEYDOWN(PHEXEDIT_DATA hed, INT VkCode) 01024 { 01025 size_t bufsize; 01026 PBYTE buf; 01027 INT i0, i1; 01028 01029 if(GetKeyState(VK_MENU) & 0x8000) 01030 { 01031 return FALSE; 01032 } 01033 01034 bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0); 01035 01036 if (hed->SelStart < hed->SelEnd) 01037 { 01038 i0 = hed->SelStart; 01039 i1 = hed->SelEnd; 01040 } 01041 else 01042 { 01043 i0 = hed->SelEnd; 01044 i1 = hed->SelStart; 01045 } 01046 01047 switch(VkCode) 01048 { 01049 case 'X': 01050 if (GetAsyncKeyState(VK_SHIFT) >= 0 && 01051 GetAsyncKeyState(VK_CONTROL) < 0 && hed->SelStart != hed->SelEnd) 01052 HEXEDIT_Cut(hed); 01053 else 01054 return TRUE; 01055 break; 01056 01057 case 'C': 01058 if (GetAsyncKeyState(VK_SHIFT) >= 0 && 01059 GetAsyncKeyState(VK_CONTROL) < 0 && hed->SelStart != hed->SelEnd) 01060 HEXEDIT_Copy(hed); 01061 else 01062 return TRUE; 01063 break; 01064 01065 case 'V': 01066 if (GetAsyncKeyState(VK_SHIFT) >= 0 && GetAsyncKeyState(VK_CONTROL) < 0) 01067 HEXEDIT_Paste(hed); 01068 else 01069 return TRUE; 01070 break; 01071 01072 case 'A': 01073 if (GetAsyncKeyState(VK_SHIFT) >= 0 && GetAsyncKeyState(VK_CONTROL) < 0) 01074 HEXEDIT_SelectAll(hed); 01075 else 01076 return TRUE; 01077 break; 01078 01079 case VK_INSERT: 01080 if (hed->SelStart != hed->SelEnd) 01081 { 01082 if (GetAsyncKeyState(VK_SHIFT) >= 0 && GetAsyncKeyState(VK_CONTROL) < 0) 01083 HEXEDIT_Copy(hed); 01084 } 01085 if (GetAsyncKeyState(VK_SHIFT) < 0 && GetAsyncKeyState(VK_CONTROL) >= 0) 01086 HEXEDIT_Paste(hed); 01087 break; 01088 01089 case VK_DELETE: 01090 if (GetAsyncKeyState(VK_SHIFT) < 0 && GetAsyncKeyState(VK_CONTROL) >= 0 && 01091 hed->SelStart != hed->SelEnd) 01092 HEXEDIT_Copy(hed); 01093 if (i0 != i1) 01094 { 01095 buf = (PBYTE) LocalLock(hed->hBuffer); 01096 if (buf) 01097 { 01098 MoveMemory(buf + i0, buf + i1, bufsize - i1); 01099 LocalUnlock(hed->hBuffer); 01100 } 01101 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize - (i1 - i0)); 01102 hed->InMid = FALSE; 01103 hed->Index = hed->SelStart = hed->SelEnd = i0; 01104 hed->CaretCol = hed->Index % hed->ColumnsPerLine; 01105 hed->CaretLine = hed->Index / hed->ColumnsPerLine; 01106 } 01107 else 01108 { 01109 if (hed->InMid && hed->EditingField) 01110 { 01111 buf = (PBYTE) LocalLock(hed->hBuffer); 01112 if (buf) 01113 { 01114 MoveMemory(buf + hed->Index, buf + hed->Index + 1, 01115 bufsize - hed->Index - 1); 01116 LocalUnlock(hed->hBuffer); 01117 } 01118 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize - 1); 01119 hed->InMid = FALSE; 01120 } 01121 else if (hed->Index < bufsize) 01122 { 01123 buf = (PBYTE) LocalLock(hed->hBuffer); 01124 if (buf) 01125 { 01126 MoveMemory(buf + hed->Index, buf + hed->Index + 1, 01127 bufsize - hed->Index - 1); 01128 LocalUnlock(hed->hBuffer); 01129 } 01130 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize - 1); 01131 } 01132 } 01133 InvalidateRect(hed->hWndSelf, NULL, TRUE); 01134 HEXEDIT_MoveCaret(hed, TRUE); 01135 break; 01136 01137 case VK_BACK: 01138 if (i0 != i1) 01139 { 01140 buf = (PBYTE) LocalLock(hed->hBuffer); 01141 if (buf) 01142 { 01143 MoveMemory(buf + i0, buf + i1, bufsize - i1); 01144 LocalUnlock(hed->hBuffer); 01145 } 01146 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize - (i1 - i0)); 01147 hed->InMid = FALSE; 01148 hed->Index = hed->SelStart = hed->SelEnd = i0; 01149 hed->CaretCol = hed->Index % hed->ColumnsPerLine; 01150 hed->CaretLine = hed->Index / hed->ColumnsPerLine; 01151 } 01152 else 01153 { 01154 if (hed->InMid && hed->EditingField) 01155 { 01156 buf = (PBYTE) LocalLock(hed->hBuffer); 01157 if (buf) 01158 { 01159 MoveMemory(buf + hed->Index, buf + hed->Index + 1, 01160 bufsize - hed->Index - 1); 01161 LocalUnlock(hed->hBuffer); 01162 } 01163 } 01164 else if (hed->Index > 0) 01165 { 01166 buf = (PBYTE) LocalLock(hed->hBuffer); 01167 if (buf) 01168 { 01169 MoveMemory(buf + hed->Index - 1, buf + hed->Index, 01170 bufsize - hed->Index); 01171 LocalUnlock(hed->hBuffer); 01172 } 01173 hed->Index--; 01174 hed->SelStart = hed->SelEnd = hed->Index; 01175 hed->CaretCol = hed->Index % hed->ColumnsPerLine; 01176 hed->CaretLine = hed->Index / hed->ColumnsPerLine; 01177 } 01178 else 01179 return TRUE; 01180 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize - 1); 01181 hed->InMid = FALSE; 01182 } 01183 InvalidateRect(hed->hWndSelf, NULL, TRUE); 01184 HEXEDIT_MoveCaret(hed, TRUE); 01185 break; 01186 01187 case VK_LEFT: 01188 if (hed->Index > 0) 01189 { 01190 hed->Index--; 01191 if (GetAsyncKeyState(VK_SHIFT) < 0) 01192 hed->SelEnd = hed->Index; 01193 else 01194 hed->SelStart = hed->SelEnd = hed->Index; 01195 hed->CaretCol = hed->Index % hed->ColumnsPerLine; 01196 hed->CaretLine = hed->Index / hed->ColumnsPerLine; 01197 hed->InMid = FALSE; 01198 InvalidateRect(hed->hWndSelf, NULL, TRUE); 01199 HEXEDIT_MoveCaret(hed, TRUE); 01200 } 01201 break; 01202 01203 case VK_RIGHT: 01204 if (hed->Index < (INT)bufsize) 01205 { 01206 hed->Index++; 01207 if (GetAsyncKeyState(VK_SHIFT) < 0) 01208 hed->SelEnd = hed->Index; 01209 else 01210 hed->SelStart = hed->SelEnd = hed->Index; 01211 hed->CaretCol = hed->Index % hed->ColumnsPerLine; 01212 hed->CaretLine = hed->Index / hed->ColumnsPerLine; 01213 hed->InMid = FALSE; 01214 InvalidateRect(hed->hWndSelf, NULL, TRUE); 01215 HEXEDIT_MoveCaret(hed, TRUE); 01216 } 01217 break; 01218 01219 case VK_UP: 01220 if (hed->Index >= hed->ColumnsPerLine) 01221 { 01222 hed->Index -= hed->ColumnsPerLine; 01223 if (GetAsyncKeyState(VK_SHIFT) < 0) 01224 hed->SelEnd = hed->Index; 01225 else 01226 hed->SelStart = hed->SelEnd = hed->Index; 01227 hed->CaretCol = hed->Index % hed->ColumnsPerLine; 01228 hed->CaretLine = hed->Index / hed->ColumnsPerLine; 01229 hed->InMid = FALSE; 01230 InvalidateRect(hed->hWndSelf, NULL, TRUE); 01231 HEXEDIT_MoveCaret(hed, TRUE); 01232 } 01233 break; 01234 01235 case VK_DOWN: 01236 if (hed->Index + hed->ColumnsPerLine <= (INT) bufsize) 01237 hed->Index += hed->ColumnsPerLine; 01238 else 01239 hed->Index = bufsize; 01240 hed->CaretCol = hed->Index % hed->ColumnsPerLine; 01241 hed->CaretLine = hed->Index / hed->ColumnsPerLine; 01242 if (GetAsyncKeyState(VK_SHIFT) < 0) 01243 hed->SelEnd = hed->Index; 01244 else 01245 hed->SelStart = hed->SelEnd = hed->Index; 01246 hed->InMid = FALSE; 01247 InvalidateRect(hed->hWndSelf, NULL, TRUE); 01248 HEXEDIT_MoveCaret(hed, TRUE); 01249 break; 01250 01251 default: 01252 return TRUE; 01253 } 01254 01255 return FALSE; 01256 } 01257 01258 static BOOL 01259 HEXEDIT_WM_CHAR(PHEXEDIT_DATA hed, WCHAR ch) 01260 { 01261 size_t bufsize; 01262 PBYTE buf; 01263 INT i0, i1; 01264 01265 bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0); 01266 if (hed->SelStart < hed->SelEnd) 01267 { 01268 i0 = hed->SelStart; 01269 i1 = hed->SelEnd; 01270 } 01271 else 01272 { 01273 i0 = hed->SelEnd; 01274 i1 = hed->SelStart; 01275 } 01276 if (!hed->EditingField) 01277 { 01278 if (0x20 <= ch && ch <= 0xFF) 01279 { 01280 if (hed->SelStart != hed->SelEnd) 01281 { 01282 buf = (PBYTE) LocalLock(hed->hBuffer); 01283 if (buf) 01284 { 01285 MoveMemory(buf + i0, buf + i1, bufsize - i1); 01286 LocalUnlock(hed->hBuffer); 01287 } 01288 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize - (i1 - i0)); 01289 hed->InMid = FALSE; 01290 bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0); 01291 hed->Index = hed->SelStart = hed->SelEnd = i0; 01292 } 01293 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize + 1); 01294 buf = (PBYTE) LocalLock(hed->hBuffer); 01295 if (buf) 01296 { 01297 MoveMemory(buf + hed->Index + 1, buf + hed->Index, 01298 bufsize - hed->Index); 01299 buf[hed->Index] = ch; 01300 LocalUnlock(hed->hBuffer); 01301 } 01302 hed->Index++; 01303 hed->CaretCol = hed->Index % hed->ColumnsPerLine; 01304 hed->CaretLine = hed->Index / hed->ColumnsPerLine; 01305 InvalidateRect(hed->hWndSelf, NULL, TRUE); 01306 HEXEDIT_MoveCaret(hed, TRUE); 01307 return FALSE; 01308 } 01309 } 01310 else 01311 { 01312 if (('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'F') || 01313 ('a' <= ch && ch <= 'f')) 01314 { 01315 if (hed->SelStart != hed->SelEnd) 01316 { 01317 buf = (PBYTE) LocalLock(hed->hBuffer); 01318 if (buf) 01319 { 01320 MoveMemory(buf + i0, buf + i1, bufsize - i1); 01321 LocalUnlock(hed->hBuffer); 01322 } 01323 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize - (i1 - i0)); 01324 hed->InMid = FALSE; 01325 bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0); 01326 hed->Index = hed->SelStart = hed->SelEnd = i0; 01327 } 01328 if (hed->InMid) 01329 { 01330 buf = (PBYTE) LocalLock(hed->hBuffer); 01331 if (buf) 01332 { 01333 if ('0' <= ch && ch <= '9') 01334 buf[hed->Index] |= ch - '0'; 01335 else if ('A' <= ch && ch <= 'F') 01336 buf[hed->Index] |= ch + 10 - 'A'; 01337 else if ('a' <= ch && ch <= 'f') 01338 buf[hed->Index] |= ch + 10 - 'a'; 01339 LocalUnlock(hed->hBuffer); 01340 } 01341 hed->InMid = FALSE; 01342 hed->Index++; 01343 } 01344 else 01345 { 01346 HexEdit_SetMaxBufferSize(hed->hWndSelf, bufsize + 1); 01347 buf = (PBYTE) LocalLock(hed->hBuffer); 01348 if (buf) 01349 { 01350 MoveMemory(buf + hed->Index + 1, buf + hed->Index, 01351 bufsize - hed->Index); 01352 if ('0' <= ch && ch <= '9') 01353 buf[hed->Index] = (ch - '0') << 4; 01354 else if ('A' <= ch && ch <= 'F') 01355 buf[hed->Index] = (ch + 10 - 'A') << 4; 01356 else if ('a' <= ch && ch <= 'f') 01357 buf[hed->Index] = (ch + 10 - 'a') << 4; 01358 LocalUnlock(hed->hBuffer); 01359 } 01360 hed->InMid = TRUE; 01361 } 01362 hed->CaretCol = hed->Index % hed->ColumnsPerLine; 01363 hed->CaretLine = hed->Index / hed->ColumnsPerLine; 01364 InvalidateRect(hed->hWndSelf, NULL, TRUE); 01365 HEXEDIT_MoveCaret(hed, TRUE); 01366 return FALSE; 01367 } 01368 } 01369 return TRUE; 01370 } 01371 01372 static LRESULT 01373 HEXEDIT_WM_SIZE(PHEXEDIT_DATA hed, DWORD sType, WORD NewWidth, WORD NewHeight) 01374 { 01375 UNREFERENCED_PARAMETER(sType); 01376 UNREFERENCED_PARAMETER(NewHeight); 01377 UNREFERENCED_PARAMETER(NewWidth); 01378 HEXEDIT_Update(hed); 01379 return 0; 01380 } 01381 01382 static VOID 01383 HEXEDIT_WM_CONTEXTMENU(PHEXEDIT_DATA hed, INT x, INT y) 01384 { 01385 HMENU hMenu; 01386 RECT rc; 01387 01388 if (x == -1 && y == -1) 01389 { 01390 GetWindowRect(hed->hWndSelf, &rc); 01391 x = rc.left; 01392 y = rc.top; 01393 } 01394 01395 hMenu = GetSubMenu(hPopupMenus, PM_HEXEDIT); 01396 if (hed->SelStart == hed->SelEnd) 01397 { 01398 EnableMenuItem(hMenu, ID_HEXEDIT_CUT, MF_GRAYED); 01399 EnableMenuItem(hMenu, ID_HEXEDIT_COPY, MF_GRAYED); 01400 EnableMenuItem(hMenu, ID_HEXEDIT_PASTE, MF_GRAYED); 01401 EnableMenuItem(hMenu, ID_HEXEDIT_DELETE, MF_GRAYED); 01402 } 01403 else 01404 { 01405 EnableMenuItem(hMenu, ID_HEXEDIT_CUT, MF_ENABLED); 01406 EnableMenuItem(hMenu, ID_HEXEDIT_COPY, MF_ENABLED); 01407 EnableMenuItem(hMenu, ID_HEXEDIT_PASTE, MF_ENABLED); 01408 EnableMenuItem(hMenu, ID_HEXEDIT_DELETE, MF_ENABLED); 01409 } 01410 01411 SetForegroundWindow(hed->hWndSelf); 01412 TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, x, y, 0, hed->hWndSelf, NULL); 01413 PostMessage(hed->hWndSelf, WM_NULL, 0, 0); 01414 } 01415 01416 INT_PTR CALLBACK 01417 HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 01418 { 01419 PHEXEDIT_DATA hed; 01420 POINTS p; 01421 01422 hed = (PHEXEDIT_DATA)(LONG_PTR)GetWindowLongPtr(hWnd, (DWORD_PTR)0); 01423 switch(uMsg) 01424 { 01425 case WM_ERASEBKGND: 01426 return TRUE; 01427 01428 case WM_PAINT: 01429 return HEXEDIT_WM_PAINT(hed); 01430 01431 case WM_KEYDOWN: 01432 return HEXEDIT_WM_KEYDOWN(hed, (INT)wParam); 01433 01434 case WM_CHAR: 01435 return HEXEDIT_WM_CHAR(hed, (WCHAR)wParam); 01436 01437 case WM_VSCROLL: 01438 return HEXEDIT_WM_VSCROLL(hed, HIWORD(wParam), LOWORD(wParam)); 01439 01440 case WM_SIZE: 01441 return HEXEDIT_WM_SIZE(hed, (DWORD)wParam, LOWORD(lParam), HIWORD(lParam)); 01442 01443 case WM_LBUTTONDOWN: 01444 { 01445 p.x = LOWORD(lParam); 01446 p.y = HIWORD(lParam); 01447 return HEXEDIT_WM_LBUTTONDOWN(hed, (INT)wParam, p); 01448 } 01449 01450 case WM_LBUTTONUP: 01451 { 01452 p.x = LOWORD(lParam); 01453 p.y = HIWORD(lParam); 01454 return HEXEDIT_WM_LBUTTONUP(hed, (INT)wParam, p); 01455 } 01456 01457 case WM_MOUSEMOVE: 01458 { 01459 p.x = LOWORD(lParam); 01460 p.y = HIWORD(lParam); 01461 return HEXEDIT_WM_MOUSEMOVE(hed, (INT)wParam, p); 01462 } 01463 01464 case WM_MOUSEWHEEL: 01465 { 01466 UINT nScrollLines = 3; 01467 int delta = 0; 01468 01469 SystemParametersInfoW(SPI_GETWHEELSCROLLLINES, 0, &nScrollLines, 0); 01470 delta -= (SHORT)HIWORD(wParam); 01471 if(abs(delta) >= WHEEL_DELTA && nScrollLines != 0) 01472 { 01473 p.x = LOWORD(lParam); 01474 p.y = HIWORD(lParam); 01475 return HEXEDIT_WM_MOUSEWHEEL(hed, nScrollLines * (delta / WHEEL_DELTA), LOWORD(wParam), &p); 01476 } 01477 break; 01478 } 01479 01480 case HEM_LOADBUFFER: 01481 return HEXEDIT_HEM_LOADBUFFER(hed, (PVOID)wParam, (DWORD)lParam); 01482 01483 case HEM_COPYBUFFER: 01484 return HEXEDIT_HEM_COPYBUFFER(hed, (PVOID)wParam, (DWORD)lParam); 01485 01486 case HEM_SETMAXBUFFERSIZE: 01487 return HEXEDIT_HEM_SETMAXBUFFERSIZE(hed, (DWORD)lParam); 01488 01489 case WM_SETFOCUS: 01490 return HEXEDIT_WM_SETFOCUS(hed); 01491 01492 case WM_KILLFOCUS: 01493 return HEXEDIT_WM_KILLFOCUS(hed); 01494 01495 case WM_GETDLGCODE: 01496 return HEXEDIT_WM_GETDLGCODE((LPMSG)lParam); 01497 01498 case WM_SETFONT: 01499 return HEXEDIT_WM_SETFONT(hed, (HFONT)wParam, (BOOL)LOWORD(lParam)); 01500 01501 case WM_GETFONT: 01502 return HEXEDIT_WM_GETFONT(hed); 01503 01504 case WM_CREATE: 01505 return HEXEDIT_WM_CREATE(hed); 01506 01507 case WM_NCCREATE: 01508 if(!hed) 01509 { 01510 return HEXEDIT_WM_NCCREATE(hWnd, (CREATESTRUCT*)lParam); 01511 } 01512 break; 01513 01514 case WM_NCDESTROY: 01515 if(hed) 01516 { 01517 return HEXEDIT_WM_NCDESTROY(hed); 01518 } 01519 break; 01520 01521 case WM_CONTEXTMENU: 01522 HEXEDIT_WM_CONTEXTMENU(hed, (short)LOWORD(lParam), (short)HIWORD(lParam)); 01523 break; 01524 01525 case WM_COMMAND: 01526 switch(LOWORD(wParam)) 01527 { 01528 case ID_HEXEDIT_CUT: 01529 HEXEDIT_Cut(hed); 01530 break; 01531 01532 case ID_HEXEDIT_COPY: 01533 HEXEDIT_Copy(hed); 01534 break; 01535 01536 case ID_HEXEDIT_PASTE: 01537 HEXEDIT_Paste(hed); 01538 break; 01539 01540 case ID_HEXEDIT_DELETE: 01541 HEXEDIT_Delete(hed); 01542 break; 01543 01544 case ID_HEXEDIT_SELECT_ALL: 01545 HEXEDIT_SelectAll(hed); 01546 break; 01547 } 01548 break; 01549 } 01550 01551 return DefWindowProc(hWnd, uMsg, wParam, lParam); 01552 } 01553 Generated on Fri May 25 2012 04:15:47 for ReactOS by
1.7.6.1
|