I am getting a memory exception in (unchanged) code that has been working for 2+ years (code is unchanged, in a Git repo).
Here's the code that is causing the exception:
HTREEITEM getTreeNode(HWND hDlg, char *name, HTREEITEM parent)
{
TV_INSERTSTRUCT tvinsert = {};
tvinsert.hParent = parent;
tvinsert.hInsertAfter = parent ? TVI_SORT : TVI_ROOT;
tvinsert.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvinsert.item.pszText = name;
tvinsert.item.lParam = -1;
tvinsert.item.iImage = 0;
tvinsert.item.iSelectedImage = 1;
if (IsWindow(hDlg))
LogError("**** window ok");
else
LogError("**** Window issue....");
HWND presetHDlg = GetDlgItem(hDlg, IDC_PRESET_TREE);
if (IsWindow(presetHDlg))
LogError("**** Preset Tree window ok");
else
LogError("**** Preset Tree Window issue....");
HTREEITEM newNode = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_PRESET_TREE,
TVM_INSERTITEM, 0, (LPARAM)&tvinsert);
if (nodes == NULL)
{ ...
The exception occurs when calling SendDlgItemMessage()
, and both IsWindow()
calls return TRUE.
Prior to calling this function, another call to SendDlgItemMessage()
to the same control, to set the bitmap/image list, works without an issue:
void addPresetsTree(HWND hDlg)
{
// Load bitmaps used in tree view
HIMAGELIST hImageList = ImageList_Create(16, 16, ILC_COLOR16, 2, 10);
HBITMAP hBitMap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_OPEN_FOLDER));
if (hBitMap == NULL) LogError("*** Failed to load bitmap for IDB_OPEN_FOLDER");
else
{
ImageList_Add(hImageList, hBitMap, NULL);
DeleteObject(hBitMap);
}
hBitMap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_CLOSED_FOLDER));
if (hBitMap == NULL) LogError("*** Failed to load bitmap for IDB_CLOSED_FOLDER");
else
{
ImageList_Add(hImageList, hBitMap, NULL);
DeleteObject(hBitMap);
}
hBitMap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PRESET));
if (hBitMap == NULL) LogError("*** Failed to load bitmap for IDB_PRESET");
else
{
ImageList_Add(hImageList, hBitMap, NULL);
DeleteObject(hBitMap);
}
hBitMap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SELECTED_PRESET));
if (hBitMap == NULL) LogError("*** Failed to load bitmap for IDB_SELECTED_PRESET");
else
{
ImageList_Add(hImageList, hBitMap, NULL);
DeleteObject(hBitMap);
}
LRESULT res = SendDlgItemMessage(hDlg, IDC_PRESET_TREE, TVM_SETIMAGELIST, 0, (LPARAM)hImageList);
HTREEITEM Parent = NULL;
char p[] = "RootNode";
Parent = getTreeNode(hDlg, p, Parent);
}
This code is called on receiving the WM_INITDIALOG
message in the dialog proc:
BOOL CALLBACK FindPresetDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
InitCommonControls(); // make our tree control work
// Populate preset tree and select current entry, if available
addPresetsTree(hDlg);
break;
...
The strange thing is that this code has been working for several years, and I only noticed this exception in June this year (last working build I have is from April). I keep my source under Git, and all old version releases, previously all working, now give this exception.
The stack trace shows the following Windows DLL modules are called:
KernelBase.dll!MultiByteToWideChar()
comctl32.dll!ProduceWFromA()
comctl32.dll!TV_InsertItemA(struct _TREE *,struct tagTVINSERTSTRUCTA *)
comctl32.dll!TV_WndProc(struct HWND__ *,unsigned int,unsigned __int64,__int64)
user32.dll!UserCallWinProcCheckWow(struct _ACTIVATION_CONTEXT *,__int64 (*)(struct tagWND *,unsigned int,unsigned __int64,__int64),struct HWND__ *,enum _WM_VALUE,unsigned __int64,__int64,void *,int)
user32.dll!SendMessageWorker()
user32.dll!SendMessageInternal(struct HWND__ *,unsigned int,unsigned __int64,__int64,int)
user32.dll!SendMessageA()
user32.dll!SendDlgItemMessageA()
FSUIPC7.exe!getTreeNode(HWND__ * hDlg, char * name, _TREEITEM * parent) Line 76
at E:\Repos\MyApp\MyApp\FindPreset.cpp(76)
MyApp.exe!addPresetsTree(HWND__ * hDlg) Line 151
at E:\Repos\MyApp\MyApp\FindPreset.cpp(151)
MyApp.exe!FindPresetDlgProc(HWND__ * hDlg, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 216
at E:\Repos\MyApp\MyApp\FindPreset.cpp(216)
I can only assume that this exception must be due to either a change in one of those Windows DLLs, or maybe due to a change/update of Visual Studio 2022.
I have also tried creating a minimal app to show the issue, using the same code, but I get no exception in this app - it works just fine.
Note that I also had a catastrophic failure caused by a Windows Insider update shortly after discovering this issue, and I have had to completely re-install Windows 11 (no backup!). This error is still present, but I have no history of any Windows or Visual Studio updates. All I can know is that the last working version of this app was built on April 9th 2025, and every build after this has this error.
I'm not sure what I can do now to determine what is causing this exception - does anyone have any ideas on what could cause this, or what I can do to track this down?
Here's the GitHub Copilot report (for what it's worth!):
The exception is an access violation (0xC0000005) caused by attempting to read from an invalid memory location (0x00000000000000E4). The immediate cause is the SendDlgItemMessage call in the getTreeNode function, which attempts to interact with a tree view control (IDC_PRESET_TREE) using an invalid or uninitialized HWND (presetHDlg).
Root Cause:
Invalid HWND: The GetDlgItem call to retrieve IDC_PRESET_TREE returns an invalid handle (presetHDlg), likely because hDlg is not a valid dialog handle or the control does not exist.
Uninitialized or Corrupted Data: The hDlg parameter passed to getTreeNode might be uninitialized or corrupted, leading to invalid operations.
Suggested Fix:
• Validate hDlg before calling GetDlgItem. Ensure hDlg is a valid dialog handle.
• Check if IDC_PRESET_TREE exists in the dialog resource.
This issue/exception was caused by the inclusion of a header file called wsipx2.h which has the following header:
/* WSIPX.H -- Winsock 2 Extensions for IPX networks
*
* This file contains IPX/SPX specific information for use by
* Winsock 2 comparable applications. Include this file below
* WINSOCK.H to enable IPX features in your application.
*
* Rev 0.3, Feb 23, 1995
*/
This header changed the packing to 1 but does not reset it, which I presume is the root cause. I am not sure why this file is included, and suspect the packing change was added many years ago by the original author of this program.
I have removed this header file and all is now good.
One thing still puzzles me though: the code hasn't changed for many years, and only recently started causing this issue with no code change and no other change that I can think of (although there were VS and OS updates, a friend verified on a lot older version of both and the error/exception was still present.