size_w InsertTypeGV(HWND hwndGridView, HGRIDITEM hRoot, TypeDecl *typeDecl, size_w dwOffset) { GVITEM gvitem = { 0 }; size_w dwLength = 0; ExprNode * offsetExpr; // typedef statements are never displayed if(typeDecl->typeAlias == true) return dwOffset; if(typeDecl->declList.size() == 0 && typeDecl->nested) { if(FindTag(typeDecl->tagList, TOK_OFFSET, &offsetExpr)) { UINT64 r; HWND hwndHV = GetActiveHexView(g_hwndMain); //dwOffset += Evaluate(offsetExpr); r = sizeof(IMAGE_DOS_HEADER); Evaluate(hRoot, offsetExpr, &r, dwOffset, hwndHV, hwndGridView); dwOffset = r & 0xffff; } // embedded struct/union that has no variables (i.e. just a plain unnamed struct decl) // don't insert a gridview item for the struct/union name, this means that // the embedded struct members get added at the same level as the parent's members dwLength += RecurseType(hwndGridView, hRoot, typeDecl->baseType, dwOffset, typeDecl); return dwLength; } else { // display each variable-decl size_t i; for(i = 0; i < typeDecl->declList.size(); i++) { Type *type = typeDecl->declList[i]; if(FindTag(typeDecl->tagList, TOK_OFFSET, &offsetExpr)) { UINT64 r; HWND hwndHV = GetActiveHexView(g_hwndMain); Evaluate(hRoot,//typeDecl->parent->sptr, offsetExpr, &r, dwOffset, hwndHV, hwndGridView); } // always an IDENTIFER at this point //HGRIDITEM hChild = GridView_InsertChild(hwndGridView, hRoot, &gvitem); //TRACEA("*** %d: %s\n", type->ty, type->sym->name); //dwLength += RecurseType(hwndGridView, hChild, type, dwOffset + dwLength, typeDecl); //TRACEA("*** %d: %s\n", type->ty, type->sym->name); dwLength += RecurseType(hwndGridView, hRoot, type, dwOffset + dwLength, typeDecl); } } return dwLength; }
BOOL HexSaveCurrent(HWND hwndMain) { HWND hwndHV; // shall we use the (untitled) document or create a new window? hwndHV = GetActiveHexView(hwndMain); // if(HexView_SaveFile(hwndHV, 0, NULL)) { return TRUE; } return FALSE; }
BOOL HexSaveAs(HWND hwndMain, LPCTSTR szFileName) { HWND hwndHV = GetActiveHexView(hwndMain); if(szFileName == 0) return FALSE; // if(HexView_SaveFile(hwndHV, szFileName, FALSE)) { UpdateCurFileName(hwndMain, hwndHV, szFileName, FALSE); return TRUE; } else { return FALSE; } }
LRESULT CALLBACK HighlightViewCommandHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { extern HWND g_hwndMain; HWND hwndHV = GetActiveHexView(g_hwndMain); if (msg == WM_COMMAND) { switch (LOWORD(wParam)) { case IDC_HIGHLIGHT_ADD: HighlightDlg(NULL, NULL); break; case IDC_HIGHLIGHT_EDIT: { HWND hwndGridView = GetDlgItem(hwnd, IDC_HIGHLIGHT_GRIDVIEW); ULONG curSelItem = GridView_GetCurSel(hwndGridView); HGRIDITEM hgCurSelItem = GridView_GetItemHandle(hwndGridView, curSelItem); GVITEM curItem = { GVIF_PARAM, curSelItem, 0 }; // Get the current item - param contains the HBOOKMARK for this item if (GridView_GetItem(hwndGridView, hgCurSelItem, &curItem) && curItem.param) { HBOOKMARK hbm = (HBOOKMARK)curItem.param; // Get the parent item - param contains the HWND for the hexview if (GridView_GetParentItem(hwndGridView, hgCurSelItem, &curItem) && curItem.param) { HWND hwndHexView = (HWND)curItem.param; HighlightDlg(hwndHexView, hbm); } } break; } case IDC_HIGHLIGHT_DELETE: { TCHAR itemText[100] = { 0 }; HWND hwndGridView = GetDlgItem(hwnd, IDC_HIGHLIGHT_GRIDVIEW); ULONG curSelItem = GridView_GetCurSel(hwndGridView); HGRIDITEM hgCurSelItem = GridView_GetItemHandle(hwndGridView, curSelItem); GVITEM curItem = { GVIF_PARAM | GVIF_TEXT, curSelItem, 0 }; curItem.pszText = itemText; curItem.cchTextMax = ARRAYSIZE(itemText); // Get the current item - param contains the HBOOKMARK for this item if (GridView_GetItem(hwndGridView, hgCurSelItem, &curItem)) { if (curItem.param) { HBOOKMARK hbm = (HBOOKMARK)curItem.param; // Get the parent item - param contains the HWND for the hexview if (GridView_GetParentItem(hwndGridView, hgCurSelItem, &curItem) && curItem.param) { HWND hwndHexView = (HWND)curItem.param; GridView_DeleteItem(hwndGridView, hgCurSelItem); HexView_DelBookmark(hwndHexView, hbm); GridView_Update(hwndGridView); } } else { // This wasn't a live bookmark - it exists in a config file TCHAR parentText[100] = { 0 }; curItem.pszText = parentText; if (GridView_GetParentItem(hwndGridView, hgCurSelItem, &curItem)) { DeleteBookmarkFromConfig(parentText, itemText); GridView_DeleteAll(hwndGridView); UpdateHighlights(TRUE); } } } break; } } return 0; } if(msg == WM_NOTIFY) { NMGRIDVIEW *nmgv = (NMGRIDVIEW *)lParam; if(nmgv->hdr.code == GVN_DBLCLK) { GVITEM gvi = { GVIF_PARAM, nmgv->iItem, 0 };//nmgv->nColumn }; if(GridView_GetParent(nmgv->hdr.hwndFrom, nmgv->hItem)) { if(GridView_GetItem(nmgv->hdr.hwndFrom, nmgv->hItem, &gvi)) { // file is not open yet! if(gvi.param == 0) { TCHAR szFileName[MAX_PATH]; gvi.mask |= GVIF_TEXT; gvi.pszText = szFileName; gvi.cchTextMax = MAX_PATH; if(GridView_GetParentItem(nmgv->hdr.hwndFrom, nmgv->hItem, &gvi)) { HexOpenFile(g_hwndMain, szFileName, DefaultFileMode()); } } else { HighlightDlg(hwndHV, (HBOOKMARK)gvi.param); } } } } else if(nmgv->hdr.code == GVN_DELETED) { GVITEM gvi = { GVIF_PARAM, nmgv->iItem, 0 };//nmgv->nColumn }; //HIGHLIGHT_PARAM hp; // get current item in gridview GridView_GetItem(nmgv->hdr.hwndFrom, nmgv->hItem, &gvi); HexView_DelBookmark(hwndHV, (HBOOKMARK)gvi.param); return 0; } else if(nmgv->hdr.code == GVN_SELCHANGED) { GVITEM gvi = { GVIF_PARAM, nmgv->iItem, 0 };//nmgv->nColumn }; BOOKMARK bm; // get the gvi.param - contains the HBOOKMARK for this bookmark entry if(GridView_GetItem(nmgv->hdr.hwndFrom, nmgv->hItem, &gvi) && gvi.param) { HBOOKMARK hbm = (HBOOKMARK)gvi.param; // get parent item's param - contains HWND to the hexview if(GridView_GetParentItem(nmgv->hdr.hwndFrom, nmgv->hItem, &gvi) && gvi.param) { // make sure the current file is active hwndHV = (HWND)gvi.param; HexSetCurFileHwnd(g_hwndMain, hwndHV); if(HexView_GetBookmark(hwndHV, hbm, &bm)) { HexView_SetCurPos(hwndHV, bm.offset + bm.length); HexView_SetSelStart(hwndHV, bm.offset); HexView_SetSelEnd(hwndHV, bm.offset + bm.length); HexView_ScrollTo(hwndHV, bm.offset + bm.length); InvalidateRect(hwndHV,0,0); } } } return 0; } } return 0; }
INT_PTR CALLBACK HighlightDlgProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static BOOL fMask = FALSE; static HWND hwndHV; size_w offset, length; BOOKMARK bm = {0}; static TCHAR title[100]; static TCHAR text[200]; static int count; static HBOOKMARK hbm; switch (iMsg) { case WM_INITDIALOG: hwndHV = GetActiveHexView(GetParent(hwnd)); // GetOwner(hwnd);// SendDlgItemMessage(hwnd, IDC_NAME, EM_SETCUEBANNER, TRUE, (LPARAM)TEXT("Enter some descriptive text here")); SendDlgItemMessage(hwnd, IDC_ANNOTATION, EM_SETCUEBANNER, 0, (LPARAM)TEXT("Enter some descriptive text here")); //MakeColourCombo(GetDlgItem(hwnd, IDC_COMBO1), fgcollist, fgtextlist, 16); MakeColourCombo(GetDlgItem(hwnd, IDC_COMBO4), bgcollist, bgtextlist, 16); hbm = (HBOOKMARK)lParam; if(hbm == 0) { HexView_GetSelStart(hwndHV, &offset); HexView_GetSelSize(hwndHV, &length); wsprintf(title, TEXT("bookmark-%03d"), ++count); //lstrcpy(title, TEXT(""));//TEXT("Enter some descriptive text here")); lstrcpy(text, TEXT(""));//TEXT("Enter some descriptive text here")); } else { HBOOKMARK hbm = (HBOOKMARK)lParam; BOOKMARK bm; HexView_GetBookmark(hwndHV, hbm, &bm); offset = bm.offset; length = bm.length; lstrcpy(title, bm.pszTitle); lstrcpy(text, bm.pszText); // Set the selected color for (int i = 0; i < 16; i++) { if (bm.backcol == bgcollist[i]) { SendMessage(GetDlgItem(hwnd, IDC_COMBO4), CB_SETCURSEL, i, 0); break; } } } SetDlgItemBaseInt(hwnd, IDC_OFFSET, offset, 16, 1); SetDlgItemBaseInt(hwnd, IDC_LENGTH, length, 16, 1); SetDlgItemText(hwnd, IDC_NAME, title); SetDlgItemText(hwnd, IDC_ANNOTATION, text); //ClientToScreen(hwndParent, &pt); //GetCursorPos(&pt); //SetWindowPos(hwnd, 0, pt.x, pt.y, 0, 0, SWP_NOSIZE); CenterWindow(hwnd); return TRUE; case WM_CLOSE: EndDialog(hwnd, FALSE); return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: GetDlgItemText(hwnd, IDC_ANNOTATION, text, 200); GetDlgItemText(hwnd, IDC_NAME, title, 100); bm.col = 0; bm.backcol = GetColourComboRGB(GetDlgItem(hwnd, IDC_COMBO4));//RGB(rand()+128, rand()+128, rand()+128);//0xffffff; bm.pszText = text; bm.pszTitle = title; bm.offset = GetDlgItemBaseInt(hwnd, IDC_OFFSET, 16); bm.length = GetDlgItemBaseInt(hwnd, IDC_LENGTH, 16); if(hbm == 0) { HexView_AddBookmark(hwndHV, &bm); } else { HexView_SetBookmark(hwndHV, hbm, &bm); } // DockWnd_UpdateContent(g_hwndMain, DWID_HIGHLIGHT); ///UpdateHighlights(hwndHV, hwndGridView); EndDialog(hwnd, TRUE); return 0; case IDCANCEL: EndDialog(hwnd, FALSE); return 0; default: return FALSE; } default: break; } return FALSE; }
// // Main Window message handler // LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { NMHDR *hdr; POINT pt; RECT rect; HMENU hMenu; HWND hwndHV = GetActiveHexView(hwnd);//g_hwndHexView; int i; TCITEM tci; MAINWND *mainWnd = (MAINWND *)GetWindowLongPtr(hwnd, 0); switch(msg) { case WM_NCCREATE: if((mainWnd = malloc(sizeof(MAINWND))) == 0) return FALSE; SetWindowLongPtr(hwnd, 0, (LONG_PTR)mainWnd); ZeroMemory(mainWnd, sizeof(MAINWND)); return TRUE; case WM_NCDESTROY: free(mainWnd); return 0; case WM_CREATE: g_hwndMain = hwnd; SetWindowIcon(hwnd, IDI_APP); // create a child-window EDIT control //g_hwndHexView = CreateHexViewCtrl(hwnd); g_hwndTabView = CreateWindow(WC_TABVIEW, TEXT(""), WS_CHILD|WS_VISIBLE,0,0,0,0,hwnd, 0, g_hInstance, 0); g_hwndStatusBar = CreateStatusBar(hwnd); SendMessage(g_hwndTabView, TCM_SETITEMSIZE, 0, MAKELPARAM(150, 0)); SetStatusBarParts(g_hwndStatusBar); hwndHV = g_hwndHexView; mainWnd->hwndMain = hwnd; mainWnd->hwndStatusBar = g_hwndStatusBar; mainWnd->hwndTabView = g_hwndTabView; CreateToolTip(g_hwndHexView); // g_hwndDock[0] = CreateDockWnd(&dock, hwnd, TEXT("Toolbar")); //g_hwndToolbar = InitToolbar(hwnd); //g_hwndSearchBar = CreateSearchBar(hwnd); //g_hwndTypeView = CreateTypeView(hwnd); SetFocus(hwndHV); // tell windows that we can handle drag+drop'd files DragAcceptFiles(hwnd, TRUE); UpdateRecentMenu(GetSubMenu(GetMenu(hwnd), 0)); SetTimer(hwnd, 0xdeadbeef, 1000, 0); return TRUE; case WM_TIMER: if(wParam == 0xdeadbeef) { KillTimer(hwnd, wParam); //FirstTimeOptions(hwnd); } return 0; case WM_DROPFILES: // get the screen coordinates of the drop-location if(DragQueryPoint((HDROP)wParam, &pt)) ClientToScreen(hwnd, &pt); GetWindowRect(hwndHV, &rect); // drop anywhere *except* the hexview, as that does D&D itself if(!PtInRect(&rect, pt)) { HandleDropFiles(hwnd, (HDROP)wParam); } //CreateToolTip(mainWnd->hwndTabView); return 0; case WM_ENABLE: EnableWindow(g_hwndSearch, (BOOL)wParam); EnableWindow(g_hwndGoto, (BOOL)wParam); return 0; case WM_CONTEXTMENU: if((HWND)wParam == DockWnd_GetWindow(hwnd, DWID_TYPEVIEW)) { HMENU hMenu = GetSubMenu(LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_TYPECONTEXT)), 0); UINT u; MenuCheckMark(hMenu, IDM_TYPEVIEW_HEX, g_fDisplayHex); MenuCheckMark(hMenu, IDM_TYPEVIEW_BIGENDIAN, g_fDisplayBigEndian); u = TrackPopupMenu(hMenu, TPM_RETURNCMD, (short)LOWORD(lParam), (short)HIWORD(lParam), 0, hwnd, 0); SendMessage(DockWnd_GetContents(hwnd, DWID_TYPEVIEW), WM_COMMAND, u, 0); } break; case WM_COMMAND: return HexEdit_OnCommand(hwnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); case WM_NOTIFY: hdr = (NMHDR *)lParam; if(hdr->hwndFrom == hwndHV) return HexViewNotifyHandler(mainWnd, hwnd, hdr); else return HexEdit_OnNotify(mainWnd, hwnd, (UINT)wParam, (NMHDR *)lParam); case WM_CLOSE: tci.mask = TCIF_PARAM; for(i = 0; (hwndHV = EnumHexView(hwnd, i)) != NULL; ) { UINT uAnswer = HexFileCloseNotify(hwnd, hwndHV); if(uAnswer == IDCANCEL) { return 0; } else if(uAnswer == IDNO) { SaveHighlights(hwndHV); TabCtrl_DeleteItem(mainWnd->hwndTabView, i); } else { i++; } } // save settings *before* we destroy anything! DockWnd_SaveSettings(hwnd); // shut program down DestroyWindow(hwnd); return 0; case WM_DESTROY: DestroyWindow(hwndHV); // PostQuitMessage(0); return 0; case WM_SETFOCUS: SetFocus(hwndHV); return 0; case WM_SIZE: MainWndSize(mainWnd, LOWORD(lParam), HIWORD(lParam)); UpdateStatusbar(mainWnd->hwndStatusBar); return 0; case WM_INITMENUPOPUP: hMenu = (HMENU)wParam;//GetMenu(hwnd); MenuCheckMark(hMenu, IDM_VIEW_TOOLBAR, DockWnd_IsOpen(hwnd, DWID_TOOLBAR)); MenuCheckMark(hMenu, IDM_TOOLS_TYPEVIEW, DockWnd_IsOpen(hwnd, DWID_TYPEVIEW)); MenuCheckMark(hMenu, IDM_TOOLS_SEARCHBAR, DockWnd_IsOpen(hwnd, DWID_SEARCHBAR)); CheckMenuRadioItem(hMenu, IDM_VIEW_HEX, IDM_VIEW_BIN, IDM_VIEW_HEX + (HexView_GetStyle(hwndHV) & HVS_FORMAT_MASK), MF_BYCOMMAND); { int look[32] = { 0, 0, 1, 0, 2 }; CheckMenuRadioItem(hMenu, IDM_GROUP_BYTE, IDM_GROUP_DWORD, IDM_GROUP_BYTE + look[HexView_GetGrouping(hwndHV)], MF_BYCOMMAND); } { size_w selsize; UINT edmode = HexView_GetEditMode(hwndHV); BOOL cftext = IsClipboardFormatAvailable(CF_TEXT); BOOL canundo = HexView_CanUndo(hwndHV); BOOL canredo = HexView_CanRedo(hwndHV); HexView_GetSelSize(hwndHV, &selsize); //hMenu = GetSubMenu(GetMenu(hwnd), 1); EnableMenuCmdItem(hMenu, IDM_EDIT_UNDO, canundo); EnableMenuCmdItem(hMenu, IDM_EDIT_REDO, canredo); EnableMenuCmdItem(hMenu, IDM_EDIT_CUT, selsize > 0 && edmode == HVMODE_INSERT); EnableMenuCmdItem(hMenu, IDM_EDIT_COPY, selsize > 0); EnableMenuCmdItem(hMenu, IDM_EDIT_COPYAS, selsize > 0); EnableMenuCmdItem(hMenu, IDM_EDIT_PASTE, cftext && edmode != HVMODE_READONLY ); EnableMenuCmdItem(hMenu, IDM_EDIT_PASTESPECIAL, edmode != HVMODE_READONLY ); EnableMenuCmdItem(hMenu, IDM_EDIT_DELETE, selsize > 0 && edmode != HVMODE_READONLY ); EnableMenuCmdItem(hMenu, IDM_EDIT_REVERSE, selsize > 0 && edmode != HVMODE_READONLY ); EnableMenuCmdItem(hMenu, IDM_TOOLS_TRANSFORM, selsize > 0 && edmode != HVMODE_READONLY ); EnableMenuCmdItem(hMenu, IDM_FILE_REVERT, canundo || canredo); } return 0; } return DefWindowProc(hwnd, msg, wParam, lParam); }
LRESULT HexEdit_OnNotify(MAINWND *mainWnd, HWND hwnd, UINT idCtrl, NMHDR *hdr) { HWND hwndHV = GetActiveHexView(hwnd); if(hdr->hwndFrom == mainWnd->hwndTabView) { TCITEM tci = { TCIF_PARAM }; TabCtrl_GetItem(mainWnd->hwndTabView, TabCtrl_GetCurSel(mainWnd->hwndTabView), &tci); // has the user clicked a file-tab? if(hdr->code == TCN_SELCHANGE) { HexSetCurFile(hwnd, TabCtrl_GetCurSel(mainWnd->hwndTabView), TRUE); OnFileChange(mainWnd); return 0; } else if(hdr->code == TCN_CLOSING) { // prompt close if if(HexFileCloseNotify(hwnd, hwndHV) == IDCANCEL) return TRUE; return 0; } else if(hdr->code == TCN_CLOSE) { // ask user if they want to save changes if(HexFileCloseNotify(hwnd, hwndHV) == IDCANCEL) return 0; //SetCurFile(hwnd, TabCtrl_GetCurSel(mainWnd->hwndTabView)); //DestroyWindow((HWND)tci.lParam); HexCloseFile(mainWnd, TabCtrl_GetCurSel(mainWnd->hwndTabView)); return 0; } } // double-click in a statusbar pane? if(hdr->hwndFrom == mainWnd->hwndStatusBar && hdr->code == NM_DBLCLK) { NMMOUSE *nmmouse; // statusbar is the only window at present which sends double-clicks nmmouse = (NMMOUSE *)hdr; // toggle the Readonly/Insert/Overwrite mode if(nmmouse->dwItemSpec == 4) { ToggleEditorMode(hwndHV); UpdateStatusBarText(mainWnd->hwndStatusBar, hwndHV); } return 0; } if(hdr->code == TBN_DROPDOWN) { if(GetParent(hdr->hwndFrom) == mainWnd->hwndStatusBar) { StatusBar_DropDownTB(mainWnd, hwndHV, (NMTOOLBAR *)hdr); } if(hdr->hwndFrom == mainWnd->hwndToolbar) { HexPasteSpecialDlg2(hwnd); } return 0; } /* if(hdr->code == DWN_ISDOCKABLE) { RECT rc1, rc2; // Get main window "outer" rectangle GetWindowRect(hwnd, &rc1); // Get main window "inner" rectangle GetClientRect(hwnd, &rc2); MapWindowPoints(hwnd, 0, (POINT *)&rc2, 2); InflateRect(&rc2, -2, -2); return DockWnd_GetDockSide(hwnd, (NMDOCKWNDQUERY *)hdr, &rc1, &rc2); }*/ if(hdr->code == DWN_SAVESETTINGS) { NMDOCKWNDCREATE *nmdw = (NMDOCKWNDCREATE *)hdr; TRACEA(" DWN_SAVESETTINGS: %d\n", nmdw->uId); switch(nmdw->hdr.idFrom) { case DWID_TYPEVIEW: case DWID_ALLTYPES: SaveTypeView(nmdw->hwndClient, nmdw->hKey); break; } return 0; } if(hdr->code == DWN_UPDATE_CONTENT) { NMDOCKWND *nmdw = (NMDOCKWND *)hdr; HWND hwndHV = GetActiveHexView(hwnd); switch(nmdw->hdr.idFrom) { case DWID_HIGHLIGHT: UpdateHighlights(TRUE); break; } return 0; } if(hdr->code == DWN_CREATE_CONTENT) { NMDOCKWNDCREATE *nmdw = (NMDOCKWNDCREATE *)hdr; TRACEA("DWN_CREATE_CONTENT: %d\n", hdr->idFrom); switch(nmdw->hdr.idFrom) { case DWID_TOOLBAR: mainWnd->hwndToolbar = InitToolbar(hdr->hwndFrom); return (LONG)mainWnd->hwndToolbar; case DWID_SEARCHBAR: return (LONG)CreateSearchBar(hdr->hwndFrom); case DWID_ALLTYPES: //SendMessage(hwndTB, TB_SETSTATE, IDM_TOOLS_TYPEVIEW, DockWnd_IsOpen(g_hwndMain, DWID_TYPEVIEW) ? TBSTATE_CHECKED|TBSTATE_ENABLED : TBSTATE_ENABLED); return (LONG)CreateTypeView(hdr->hwndFrom, nmdw->hKey, TRUE);//TEXT("struct ALL")); case DWID_TYPEVIEW: //SendMessage(hwndTB, TB_SETSTATE, IDM_TOOLS_TYPEVIEW, DockWnd_IsOpen(g_hwndMain, DWID_TYPEVIEW) ? TBSTATE_CHECKED|TBSTATE_ENABLED : TBSTATE_ENABLED); return (LONG)CreateTypeView(hdr->hwndFrom, nmdw->hKey, 0); case DWID_HIGHLIGHT: return (LONG)CreateHighlightView(hdr->hwndFrom); case DWID_STRINGS: return (LONG)CreateStringsView(hdr->hwndFrom); } } else if(hdr->code == DWN_DOCKCHANGE) { NMDOCKWND *nmdw = (NMDOCKWND *)hdr; switch(nmdw->hdr.idFrom) { case DWID_TOOLBAR: SendMessage(DockWnd_GetContents(mainWnd->hwndMain, DWID_TOOLBAR), TB_SETPARENT, (WPARAM)hdr->hwndFrom, 0); return 0; } } else if(hdr->code == DWN_CLOSING) { NMDOCKWND *nmdw = (NMDOCKWND *)hdr; switch(nmdw->hdr.idFrom) { case DWID_TYPEVIEW: break; } return 0; } return DefWindowProc(hwnd, WM_NOTIFY, idCtrl, (LONG)hdr); }
LONG HexViewNotifyHandler(MAINWND *mainWnd, HWND hwnd, NMHDR *hdr) { HWND hwndHV = GetActiveHexView(hwnd);//g_hwndHexView; NMHVPROGRESS *hvp; switch(hdr->code) { case HVN_CHANGED: mainWnd->fChanged = TRUE; UpdateToolbarState(mainWnd->hwndToolbar, hwndHV); if(g_szFileTitle[0]) { BOOL fModified = HexView_CanUndo(hwndHV); if(fModified != g_fFileChanged) { SetWindowFileName(hwnd, g_szFileTitle, fModified, FALSE); g_fFileChanged = fModified; } } UpdateTypeView(); return 0; case HVN_EDITMODE_CHANGE: // show the unicode value under the cursor //SetStatusBarText(g_hwndStatusbar, 1, 0, TEXT(" U+%04X"), // TextView_GetCurChar(g_hwndTextView) ); UpdateStatusBarText(mainWnd->hwndStatusBar, hwndHV); //SetStatusBarText(mainWnd->hwndStatusBar, 4, 0, // g_szEditMode[HexView_GetEditMode(hwndHV)] ); return 0; case HVN_CURSOR_CHANGE: UpdateStatusBarText(mainWnd->hwndStatusBar, hwndHV); UpdateToolbarState(mainWnd->hwndStatusBar, hwndHV); UpdateTypeView(); return 0; case HVN_PROGRESS: hvp = (NMHVPROGRESS *)hdr; return UpdateProgress(mainWnd, TRUE, hvp->pos, hvp->len); //return 0; case HVN_BOOKCLOSE: //HexView_DelBookmark(((NMHVBOOKMARK *)hdr)->hdr.hwndFrom, 0); //RemoveBookmark((NMHVBOOKMARK *)hdr); return 0; default: return 0; } }
void MainWndSize(MAINWND *mainWnd, int width, int height) { int statusheight; static int tabheight = 0; int toolheight; HDWP hdwp; RECT rect; RECT rcClient; HWND hwndHV = GetActiveHexView(mainWnd->hwndMain); hdwp = BeginDeferWindowPos(0); GetWindowRect(mainWnd->hwndStatusBar, &rect); statusheight = rect.bottom-rect.top; // dock out where docking windows are allowed SetRect(&rcClient, 0, 0, width, height-statusheight); //TRACEA("1: %d %d %d %d\n", rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); // Position the specified dock windows. rect will be modified to contain the // "inner" client rectangle, where we can position an MDI client, // view window, whatever // DockWnd_Position(hwnd, hdwp, &g_DockBar[0], 3, &rcClient); DockWnd_DeferPanelPos(hdwp, mainWnd->hwndMain, &rcClient); //TRACEA("2: %d %d %d %d\n", rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); if(rcClient.top > 0)//DockWnd_IsOpen(hwnd, DWID_TOOLBAR)) rcClient.top += 1; // make a resize bar //rcClient.top += 2; height = rcClient.bottom-rcClient.top; width = rcClient.right-rcClient.left; //TRACEA("3: %d %d %d %d\n", rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); if(TabCtrl_GetItemCount(mainWnd->hwndTabView) > 1) { tabheight = 32; } else { TCHAR szText[20]; TCITEM tci = { TCIF_TEXT|TCIF_PARAM, 0, 0, szText, 20 }; TabCtrl_GetItem(mainWnd->hwndTabView, 0, &tci); if(lstrcmp(szText, TEXT("(Untitled)")) == 0) tabheight = 0;//max(tabheight, 0); else tabheight =max(tabheight, 0); } //mainWnd->hwndTabView ? 32 : 0; //TRACEA("4: %d %d %d %d\n", rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); toolheight = 43; //DeferWindowPos(hdwp, g_hwndToolbar, hwnd, 0, 0, width, toolheight, SWP_NOACTIVATE|SWP_NOZORDER); //DeferWindowPos(hdwp, g_hwndDock[0], hwnd, 0, 0, width, toolheight, SWP_NOACTIVATE|SWP_NOZORDER); // // resize editbox to fit in main window //TRACEA("%d %d %d %d\n", rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); DeferWindowPos(hdwp, hwndHV, mainWnd->hwndMain, rcClient.left, rcClient.top, width, height-tabheight,SWP_NOACTIVATE|SWP_NOZORDER|SWP_SHOWWINDOW); DeferWindowPos(hdwp, mainWnd->hwndTabView, mainWnd->hwndMain, rcClient.left, rcClient.top+height-tabheight, width, tabheight, SWP_NOACTIVATE|SWP_NOZORDER); GetClientRect(mainWnd->hwndMain, &rect); DeferWindowPos(hdwp, mainWnd->hwndStatusBar, mainWnd->hwndMain, 0, rect.bottom-statusheight, rect.right, statusheight,SWP_NOACTIVATE|SWP_NOZORDER); EndDeferWindowPos(hdwp); SetStatusBarParts(mainWnd->hwndStatusBar); }
INT_PTR CALLBACK ModifyDlgProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static size_w len; HWND hwndHV = GetActiveHexView(g_hwndMain); static BOOL fHexLength = FALSE; static int nLastOperand = 0; static int nLastOperation = 0; static BOOL fBigEndian = FALSE; int basetype; static const int SearchTypeFromBaseType[] = { SEARCHTYPE_BYTE, SEARCHTYPE_WORD, SEARCHTYPE_DWORD, SEARCHTYPE_QWORD, SEARCHTYPE_BYTE, SEARCHTYPE_WORD, SEARCHTYPE_DWORD, SEARCHTYPE_QWORD, SEARCHTYPE_FLOAT, SEARCHTYPE_DOUBLE, }; switch (iMsg) { case WM_INITDIALOG: AddComboStringList(GetDlgItem(hwnd, IDC_MODIFY_DATATYPE), szTypeList, 0); AddComboStringList(GetDlgItem(hwnd, IDC_MODIFY_OPERATION), szOpList, nLastOperation); SetDlgItemBaseInt(hwnd, IDC_MODIFY_OPERAND, nLastOperand, fHexLength ? 16 : 10, FALSE); CheckDlgButton(hwnd, IDC_HEX, fHexLength ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwnd, IDC_ENDIAN, fBigEndian ? BST_CHECKED : BST_UNCHECKED); //len = HexView_GetSelSize(hwndHV); //SetDlgItemBaseInt(hwnd, IDC_MODIFY_NUMBYTES, len, fHexLength ? 16 : 10, FALSE); CenterWindow(hwnd); return TRUE; case WM_CLOSE: EndDialog(hwnd, FALSE); return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_MODIFY_OPERATION: case IDC_MODIFY_OPERAND: case IDC_MODIFY_NUMBYTES: nLastOperation = (int)SendDlgItemMessage(hwnd, IDC_MODIFY_OPERATION, CB_GETCURSEL, 0, 0); nLastOperand = (int)GetDlgItemBaseInt(hwnd, IDC_MODIFY_OPERAND, fHexLength ? 16 : 10); len = GetDlgItemBaseInt(hwnd, IDC_MODIFY_NUMBYTES, fHexLength ? 16 : 10); return TRUE; case IDC_ENDIAN: fBigEndian = IsDlgButtonChecked(hwnd, IDC_ENDIAN); return TRUE; case IDC_HEX: fHexLength = IsDlgButtonChecked(hwnd, IDC_HEX); /* len = HexView_GetSelSize(hwndHV); SetDlgItemBaseInt(hwnd, IDC_MODIFY_NUMBYTES, len, fHexLength ? 16 : 10, FALSE); */ SetDlgItemBaseInt(hwnd, IDC_MODIFY_OPERAND, nLastOperand, fHexLength ? 16 : 10, FALSE); SendDlgItemMessage(hwnd, IDC_MODIFY_OPERAND, EM_SETSEL, 0, -1); SetDlgItemFocus(hwnd, IDC_MODIFY_OPERAND); return TRUE; case IDOK: // get the basetype we are using basetype = (int)SendDlgItemMessage(hwnd, IDC_INSERT_DATATYPE, CB_GETCURSEL, 0, 0); basetype = SearchTypeFromBaseType[basetype]; // get the operand in raw-byte format, ensure it is always little-endian // as we must do these calculations using the native byte ordering format operandLen = sizeof(operandData); UpdateSearchData(GetDlgItem(hwnd, IDC_MODIFY_OPERAND), basetype, FALSE, operandData, &operandLen); HexView_GetSelSize(hwndHV, &len); ModifyHexViewData(hwndHV, nLastOperation, operandData, len, basetype, fBigEndian); EndDialog(hwnd, TRUE); return TRUE; case IDCANCEL: EndDialog(hwnd, FALSE); return TRUE; default: return FALSE; } case WM_HELP: return HandleContextHelp(hwnd, lParam, IDD_TRANSFORM); default: break; } return FALSE; }
// // hwndGV - handle to GridView control // hRoot - root item-handle // type - node in the type-chain // dwOffset - current offset // // returns: size of type // size_w RecurseType(HWND hwndGV, HGRIDITEM hRoot, Type *type, size_w dwOffset, TypeDecl *typeDecl) { GVITEM gvitem = { 0 }; Structure *sptr; size_t i; TCHAR buf[200]; if(type == 0) return 0; size_w dwLength = 0; INUMTYPE switchVal = 0;//1; HWND hwndHV = GetActiveHexView(g_hwndMain); switch(type->ty) { case typeDOSTIME: case typeDOSDATE: case typeFILETIME: case typeTIMET: dwLength = FmtData(hwndGV, hRoot, type, dwOffset, typeDecl); break; case typeCHAR: case typeWCHAR: case typeBYTE: case typeWORD: case typeDWORD: case typeQWORD: case typeFLOAT: case typeDOUBLE: case typeENUM: dwLength = FmtData(hwndGV, hRoot, type, dwOffset, typeDecl); break; case typeUNION: // evaluate the switch_is() ExprNode *switchExpr; if(FindTag(typeDecl->tagList, TOK_SWITCHIS, &switchExpr)) { switchVal = Evaluate(switchExpr); } sptr = type->sptr; for(i = 0; i < sptr->typeDeclList.size(); i++) { TypeDecl *typeDecl = sptr->typeDeclList[i]; ExprNode *caseExpr; size_w tmpLen = 0; if(FindTag(typeDecl->tagList, TOK_CASE, &caseExpr)) { if(Evaluate(caseExpr) == switchVal) tmpLen = InsertTypeGV(hwndGV, hRoot, typeDecl, dwOffset); } else { tmpLen = InsertTypeGV(hwndGV, hRoot, typeDecl, dwOffset); } dwLength = max(dwLength, tmpLen); } break; case typeSTRUCT: sptr = type->sptr; for(i = 0; i < sptr->typeDeclList.size(); i++) { TypeDecl *typeDecl = sptr->typeDeclList[i]; dwLength += InsertTypeGV(hwndGV, hRoot, typeDecl, dwOffset + dwLength); } break; case typeIDENTIFIER: hRoot = InsertIdentifier(hwndGV, hRoot, type, dwOffset, typeDecl); dwLength = RecurseType(hwndGV, hRoot, type->link, dwOffset, typeDecl); break; #if 0 if(fShowFullType) { RenderType(buf, 200, type); gvitem.pszText = buf; } else { _stprintf(buf, TEXT("%hs"), type->sym->name); gvitem.pszText = buf;//type->sym->name; } gvitem.state = 0; if(type->link && type->link->ty != typeARRAY) gvitem.state |= GVIS_EXPANDED; gvitem.iImage = IsStruct(type) ? 1 : 0; if(typeDecl->tagList) gvitem.iImage+=2; gvitem.param = (ULONG_PTR)type;//typeDecl; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE | GVIF_IMAGE; GridView2_SetItem(hwndGV, hRoot, &gvitem); if(type->link && type->link->ty == typeARRAY) { FormatDataItem(hwndGV, hRoot, type, dwOffset); } if(IsStruct(type)) { gvitem.iSubItem = COLIDX_DATA; gvitem.state = GVIS_READONLY; gvitem.pszText = TEXT("{...}"); gvitem.param = 0; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); } if(!fShowFullType) { RenderType(buf, 200, type->link); //_stprintf(buf, TEXT("%hs"), type->sym->name); gvitem.iSubItem = 0;//COLIDX_TYPE; gvitem.state = GVIS_READONLY; gvitem.pszText = buf; gvitem.param = (UINT64)type; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); } dwLength = RecurseType(hwndGV, hRoot, type->link, dwOffset, typeDecl); break; #endif case typeTYPEDEF: case typeSIGNED: case typeUNSIGNED: case typeCONST: // return 0; case typePOINTER: dwLength = RecurseType(hwndGV, hRoot, type->link, dwOffset, typeDecl); break; case typeARRAY: Symbol *sym; ExprNode *nameExpr; if(FindTag(typeDecl->tagList, TOK_NAME, &nameExpr)) { if((sym = LookupSymbol(globalTagSymbolList, nameExpr->str)) != 0) { if(sym->type && sym->type->ty == typeENUM) ; else sym = 0; } } else { sym = 0; } UINT64 count; count = 0; Evaluate(GridView_GetParent(hwndGV, hRoot), type->elements, &count, dwOffset, hwndHV, hwndGV); count &= 0xffff; count = min(count,100); for(i = 0; i < count; i++) { HGRIDITEM hItem; TCHAR buf[164]; int len = _stprintf(buf, TEXT("[%d] "), (int)i); if(sym) { Enum *eptr = sym->type->eptr; char *s = 0; for(size_t x = 0; x < eptr->fieldList.size(); x++) { if(i == eptr->fieldList[x]->val) { s = eptr->fieldList[i]->name->name; } } _stprintf(buf + 5, TEXT("- %hs"), s); } gvitem.pszText = buf; gvitem.state = GVIS_READONLY; gvitem.iImage = 0;//rand() % 2; gvitem.param = (ULONG_PTR)type->link; gvitem.iSubItem = COLIDX_NAME; gvitem.mask = GVIF_STATE|GVIF_PARAM|GVIF_TEXT; hItem = GridView2_InsertUniqueChild(hwndGV, hRoot, &gvitem); // used to pass '0' as typeDecl??? why?? because this is an array element we // are recursing through!!!! dwLength += RecurseType(hwndGV, hItem, type->link, dwOffset + dwLength, 0);//typeDecl); } break; default: break; } // add the 'offset' column to all items if(hRoot) { _stprintf(buf, TEXT("%08x"), (DWORD)dwOffset); gvitem.pszText = buf; gvitem.iSubItem = COLIDX_OFFSET; gvitem.state = 0; gvitem.param = dwOffset; gvitem.mask = GVIF_TEXT | GVIF_STATE | GVIF_PARAM; GridView2_SetItem(hwndGV, hRoot, &gvitem); // add the 'comment' column item - only do this for items that aren't array elements if(typeDecl)// && type->ty != typeARRAY) { FILEREF *ref; ref = &typeDecl->postRef; buf[0] = '\0'; FormatWhitespace(ref, buf); gvitem.pszText = buf; gvitem.iSubItem = COLIDX_COMMENT; gvitem.state = 0; gvitem.mask = GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); } } return dwLength; }
// // offset - offset to read data from for this item // size_w FmtData(HWND hwndGV, HGRIDITEM hRoot, Type *type, size_w dwOffset, TypeDecl *typeDecl) { GVITEM gvitem = { 0 }; Enum *eptr; TCHAR buf[200]; double f; size_t i; DWORD typeLenLookup[] = { 0, 1, 2, 1, 2, 4, 8, 4, 8, 4, 2, 2, 4, 8 }; // TCHAR *typeFmtLookupHex2[] = { 0, TEXT("%#02x \'%c\'"), TEXT("%#04x '%lc\'"), TEXT("%#02x"), TEXT("%#04x"), TEXT("%#08x"), TEXT("%#0I64x"), TEXT("%#g"), TEXT("%#g") }; TCHAR *typeFmtLookupHex[] = { 0, TEXT("%02x \'%c\'"), TEXT("%04x '%lc\'"), TEXT("%02x"), TEXT("%04x"), TEXT("%08x"), TEXT("%0I64x"), TEXT("%#g"), TEXT("%#g") }; TCHAR *typeFmtLookupSigned[] = { 0, TEXT("%d \'%c\'"), TEXT("%d \'%lc\'"), TEXT("%d"), TEXT("%hd"), TEXT("%d"), TEXT("%I64d"), TEXT("%#g"), TEXT("%#g") }; TCHAR *typeFmtLookupUnsigned[] = { 0, TEXT("%u \'%c\'"), TEXT("%u \'%lc\'"), TEXT("%u"), TEXT("%hu"), TEXT("%u"), TEXT("%I64u"), TEXT("%#g"), TEXT("%#g") }; TCHAR *fmt; bool displaySigned = false; BOOL displayHex = g_fDisplayHex; bool bigEndian = false; TYPE baseType = BaseType(type); bool displayEnum = false; Enum *baseEnum = 0; displaySigned = FindType(type, typeSIGNED) ? true : false; if(typeDecl) { ExprNode *expr; if(FindTag(typeDecl->tagList, TOK_ENDIAN, &expr)) { if(strcmp(expr->str, "big") == 0) bigEndian = true; } if(FindTag(typeDecl->tagList, TOK_ENUM, &expr)) { baseEnum = FindEnum(expr->str); displayEnum = true; } } if(displayHex) fmt = typeFmtLookupHex[baseType]; else if(displaySigned) fmt = typeFmtLookupSigned[baseType]; else fmt = typeFmtLookupUnsigned[baseType]; BYTE HexData[8]; HWND hwndHV = GetActiveHexView(g_hwndMain); DWORD numread; numread = HexView_GetData(hwndHV, dwOffset, (BYTE *)&HexData, sizeof(HexData)); DWORD dwLength = typeLenLookup[type->ty]; if(numread < dwLength) { gvitem.pszText = TEXT(""); gvitem.iSubItem = COLIDX_DATA; gvitem.state = 0; gvitem.mask = GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); return typeLenLookup[type->ty]; } if(bigEndian || g_fDisplayBigEndian) reverse(HexData, dwLength); if(FindType(type, typeDOSDATE)) baseType = type->ty; if(FindType(type, typeDOSTIME)) baseType = type->ty; if(FindType(type, typeFILETIME))baseType = type->ty; if(FindType(type, typeTIMET)) baseType = type->ty; if(displayEnum) { if(BaseType(type) == typeENUM) eptr = BaseNode(type)->eptr; else eptr = baseEnum; WORD *wptr = (WORD *)(&HexData[0]); _stprintf(buf, TEXT("%04x"), *wptr); for(i = 0; i < eptr->fieldList.size(); i++) { if(Evaluate(eptr->fieldList[i]->expr) == *wptr) { _stprintf(buf, TEXT("%hs"), eptr->fieldList[i]->name->name); break; } } gvitem.pszText = buf; gvitem.iSubItem = COLIDX_DATA; gvitem.state = GVIS_DROPDOWN; gvitem.mask = GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); return SizeOf(type, 0, 0); } else { struct DOSDATE { WORD day : 5; WORD month : 4; WORD year : 7; } *dosdate = (DOSDATE *)HexData; struct DOSTIME { WORD sec : 5; WORD min : 6; WORD hour : 5; } *dostime = (DOSTIME *)HexData; FILETIME ft; SYSTEMTIME st; switch(baseType) { case typeDOSTIME: _stprintf(buf, TEXT("%02d:%02d:%02d"), dostime->hour, dostime->min, dostime->sec); break; case typeDOSDATE: _stprintf(buf, TEXT("%02d/%02d/%04d"), dosdate->day, dosdate->month, dosdate->year); break; case typeTIMET: UnixTimeToFileTime(*(time_t *)HexData, &ft); FileTimeToSystemTime((FILETIME *)HexData, &st); _stprintf(buf, TEXT("%02d/%02d/%04d %02d:%02d:%02d"), st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond); break; case typeFILETIME: FileTimeToSystemTime((FILETIME *)HexData, &st); _stprintf(buf, TEXT("%02d/%02d/%04d %02d:%02d:%02d"), st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond); break; case typeCHAR: _stprintf(buf, fmt, HexData[0], HexData[0] < ' ' ? '.' : HexData[0]); break; case typeWCHAR: _stprintf(buf, fmt, *(WCHAR *)(&HexData[0])); break; case typeBYTE: _stprintf(buf, fmt, HexData[0]); break; case typeWORD: _stprintf(buf, fmt, *(UINT16 *)(&HexData[0])); break; case typeDWORD: _stprintf(buf, fmt, *(UINT32 *)(&HexData[0])); break; case typeQWORD: _stprintf(buf, fmt, *(UINT64 *)(&HexData[0])); break; case typeFLOAT: f = *(float *)(&HexData[0]); _stprintf(buf, fmt, f); break; case typeDOUBLE: f = *(double*)(&HexData[0]); _stprintf(buf, fmt, f); break; case typeENUM: eptr = BaseNode(type)->eptr; { WORD *wptr = (WORD *)(&HexData[0]); _stprintf(buf, TEXT("%04x"), *wptr); for(i = 0; i < eptr->fieldList.size(); i++) { if(Evaluate(eptr->fieldList[i]->expr) == *wptr) { _stprintf(buf, TEXT("%hs"), eptr->fieldList[i]->name->name); break; } } } gvitem.pszText = buf; gvitem.iSubItem = COLIDX_DATA; gvitem.state = GVIS_DROPDOWN; gvitem.mask = GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); return 4; } } gvitem.pszText = buf; gvitem.iSubItem = COLIDX_DATA; gvitem.state = 0; gvitem.mask = GVIF_TEXT | GVIF_STATE | GVIF_COLOR; gvitem.color = numread ? RGB(0,0,0) : RGB(128,128,128); GridView2_SetItem(hwndGV, hRoot, &gvitem); return typeLenLookup[type->ty]; }
void FormatDataItem(HWND hwndGV, HGRIDITEM hItem, Type *type, size_w dwOffset) { GVITEM gvitem = { 0 }; TCHAR buf[200] = TEXT(""); DWORD i, count = 20; BYTE HexData[14]; HWND hwndHV = GetActiveHexView(g_hwndMain); DWORD numread; numread = HexView_GetData(hwndHV, dwOffset, (BYTE *)&HexData, sizeof(HexData)); if(type->link->ty == typeARRAY) type = type->link->link; else return; switch(type->ty) { case typeCHAR: _stprintf(buf, TEXT("\"%hs\""), (char *)HexData); gvitem.state = 0; break; case typeDWORD: { DWORD *dwptr = (DWORD *)&HexData[0]; TCHAR *sptr = buf; sptr += _stprintf(sptr, TEXT("{ ")); for(i = 0; i < count; i++) { sptr += _stprintf(sptr, TEXT("%d, "), dwptr[i]); } sptr += _stprintf(sptr, TEXT("}")); gvitem.state = GVIS_READONLY; } case typeWORD: { WORD *dwptr = (WORD *)&HexData[0]; TCHAR *sptr = buf; sptr += _stprintf(sptr, TEXT("{ ")); for(i = 0; i < count; i++) { sptr += _stprintf(sptr, TEXT("%d, "), dwptr[i]); } sptr += _stprintf(sptr, TEXT("}")); gvitem.state = GVIS_READONLY; } break; default: gvitem.state = 0; break; } gvitem.pszText = buf; gvitem.iSubItem = COLIDX_DATA; gvitem.param = (ULONG_PTR)type; gvitem.color = numread ? RGB(0,0,0) : RGB(128,128,128); gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE | GVIF_COLOR; GridView2_SetItem(hwndGV, hItem, &gvitem); }