Random crash for MFC dialog member variable not in scope - c++

I have a MFC application with property window. I property window I have implemented a custom CMFCPropertyGridProperty, So that whenever user click the button added in that property, another dialog pops up.
void CMFCPropertyGridCustomProperty::OnClickButton(CPoint point) {
CSampleDlg* configDlg = new CSampleDlg(NULL);
INT_PTR bResult = configDlg->DoModal();
if(bResult != 1) //If user cancels bResult is 2 ,if select ok bResult is 1
{
return;
}
CString selectedOutput = configDlg->GetSelectionOutput();
CString configValue = configDlg->GetSelectionElemValue();
but the problem is , When I am running in debug mode, sometimes it is working fine but some times it crashes on configDlg->GetSelectionOutput() line. In callStack, I found that the variable is out of scope at that time.
Here is part of my dialog code:
IMPLEMENT_DYNAMIC(CSomeClassDlg, CDialogEx)
CSomeClassDlg::CSomeClassDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CSomeClassDlg::IDD, pParent)
{
m_DevNameStr = "";
m_ElemValue = "";
}
CSomeClassDlg::~CSomeClassDlg()
{
delete m_DataXMLTree;
m_DataXMLTree = NULL;
delete m_TemplateXMLTree;
m_TemplateXMLTree = NULL;
}
void CSomeClassDlg::OnItemchangedElementList(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
int nPos = -1;
nPos = m_ElementListCtrl.GetNextItem(-1,LVNI_SELECTED);
if(nPos != -1)
{
elemDataNode = (CTreeNode*)(m_ElementListCtrl.GetItemData(nSelectedItemIndex));
elemTepmplateNode = GetTemplateElement(elemDataNode);
ShowElemDescription(elemDataNode,elemTepmplateNode);
}
else
{
return;
}
*pResult = 0;
}
void CSomeClassDlg::ShowElemDescription(CTreeNode* dataElemNode, CTreeNode* templateElemNode)
{
if(dataElemNode==NULL || templateElemNode==NULL)
{
m_DescEditCtrl.SetWindowTextA("");
return;
}
CString PIXITStr = templateElemNode->GetAttributeValue("AssociatedPixit");
CString descriptionStr = templateElemNode->GetAttributeValue("Description");
CString valueStr = dataElemNode->GetAttributeValue("Value");
m_DescEditCtrl.SetWindowTextA(descriptionStr);
m_DevNameStr = PIXITStr;
m_ElemValue = valueStr;
}
CString CSomeClassDlg::GetSelectionOutput()
{
return m_DevNameStr;
}
CString CSomeClassDlg::GetSelectionElemValue()
{
return m_ElemValue;
}
But I don't understand if that is the problem then why it is not happening each time. And if it is really the problem what is the best wat to get multiple member variable after doing doModal() . Please help.

Finally I have made some changes which had solved this issue.
1.changes the constructor of custom CMFCPropertyGridProperty class , parameter specially of type COleVariant.
2.Changed the dialog class constructor to take a CTreeNode* and store it as member variable. Somehow that pointer was getting corrupted after DoModal.
3.Added some Assert() to check the validity and a Redraw() in onclickbutton() of custom CMFCPropertyGridProperty class.
I do not know the exact reason for all these changes. Found a reference code in Google code
Here is the OnClickButton of the custom CMFCPropertyGridProperty class:
void CMFCPropertyGridPropertyCustomClass::OnClickButton(CPoint point)
{
ASSERT_VALID(this);
ASSERT_VALID(m_pWndList);
ASSERT_VALID(m_pWndInPlace);
ASSERT(::IsWindow(m_pWndInPlace->GetSafeHwnd()));
m_bButtonIsDown = TRUE;
Redraw();
BOOL bUpdate = FALSE;
CString selOutput = "";
CSomeClassDlg* configDlg = new CSomeClassDlg(m_selNode);
INT_PTR bResult = configDlg->DoModal();
if(bResult == IDOK)
{
bUpdate = TRUE;
//Do Something
}
if (bUpdate)
{
if (m_pWndInPlace != NULL)
{
m_pWndInPlace->SetWindowText(selOutput);
}
m_varValue = (LPCTSTR) selOutput;
}
m_bButtonIsDown = FALSE;
Redraw();
if (m_pWndInPlace != NULL)
{
m_pWndInPlace->SetFocus();
}
else
{
m_pWndList->SetFocus();
}
}
Here is the constructor of the custom CMFCPropertyGridProperty class:
CMFCPropertyGridPropertyCustomClass::CMFCPropertyGridPropertyCustomClass(CTreeNode* pNode, const CString& strName, const CString& varValue, const CString& description) : CMFCPropertyGridProperty(strName, COleVariant((LPCTSTR)varValue), description)
{
//some initialization
}

Related

How can I change the style of a control (CListBox) initialized with DDX_Control, before DDX_Control is called

I'm modifying an existing project and a dialog has controls I am subclassing to theme differently in some cases (in other cases I will leave it entirely alone). By the time DDX_Control() is called during DoDataExchange(), the hwnd for the ListBox already has styles applied. Specifically, at this time even if I do SetWindowLongPtr(), the LBS_OWNERDRAWFIXED does not work. By "does not work," I mean that although the style is applied, owner draw messages are not received by the CListBox.
Conversely, if I avoid the DDX_Control() and simply do a create, the ListBox does receive the messages and can be ownerdrawn. But if I do this there are now two HWND, only one of which is returned by GetDlgItem(). I believe I can make this work if necessary, but I wondered if there is a secret to intercept the HWND creation of the controls in the dialog (actually a CPropertyPage).
Below is code that doesn't work, with more commented code that "works" but isn't the way I wanted it to work, if possible.
void CMyPropertySheet::DoDataExchange(CDataExchange* pDX)
{
HWND hWndCtrl;
pDX->m_pDlgWnd->GetDlgItem(IDC_LIST1, &hWndCtrl);
if (themed) {
DWORD style = GetWindowLongPtr(hWndCtrl, GWL_STYLE) | LBS_OWNERDRAWFIXED;
SetWindowLongPtr(hWndCtrl, GWL_STYLE, style);
DDX_Control(pDX, IDC_LIST1, m_listbox);
//RECT wr;
//::GetWindowRect(hWndCtrl, &wr);
//m_listbox.Create(style, wr, this, IDC_LIST1);
} else {
DDX_Control(pDX, IDC_LIST1, m_listbox);
}
I should probably add I tried subclassing the window, but it didn't help, and CMyPropertySheet::PreSubclassWindow wasn't soon enough, either.
Some creation flags like LBS_OWNERDRAWFIXED and LBS_SORT are cached and modifying them afterwards have no effect. You have to change the template, or just make a duplicate of the listbox. Copy the style of the old listbox, then hide that listbox, change its ID, and create a new listbox based on the old one. You then have to remove DDX_Control(pDX, IDC_LIST1, m_listbox)
The example below starts with a standard list which has its sort flag set. It duplicates the listbox and disables the sort option.
For simplicity this example avoids LBS_OWNERDRAWFIXED, it uses LBS_SORT instead.
class CMyPropertyPage : public CPropertyPage
{
public:
CListBox m_listbox;
int m_listbox_index;
CMyPropertyPage(int idd) : CPropertyPage(idd)
{
m_listbox_index = 1;
}
void DoDataExchange(CDataExchange* pDX)
{
//This function is automatically called before
//CPropertyPage::OnInitDialog is complete
//On the first call, IDC_LIST1 will point to the template listbox
if(m_listbox.m_hWnd)
{
//m_listbox is ready,
//IDC_LIST1 will refer to the new listbox
DDX_LBIndex(pDX, IDC_LIST1, m_listbox_index);
}
}
BOOL OnInitDialog()
{
CPropertyPage::OnInitDialog();
CListBox* old_listbox = (CListBox*)GetDlgItem(IDC_LIST1);
if(old_listbox)
{
DWORD style = ~LBS_SORT & GetWindowLongPtr(old_listbox->m_hWnd, GWL_STYLE);
CRect rc;
old_listbox->GetWindowRect(&rc);
ScreenToClient(&rc);
old_listbox->SetDlgCtrlID(0);//change the old ID to something unused
old_listbox->ShowWindow(SW_HIDE); //hide the old listbox
m_listbox.Create(style | WS_BORDER, rc, this, IDC_LIST1);
m_listbox.SetFont(GetFont());
}
ASSERT(m_listbox.GetDlgCtrlID() == IDC_LIST1);
m_listbox.AddString(L"2");
m_listbox.AddString(L"1");
m_listbox.AddString(L"0");
UpdateData(FALSE);
return TRUE;
}
};
class CMyWinApp : public CWinApp
{
BOOL InitInstance()
{
CWinApp::InitInstance();
CPropertySheet sh;
CMyPropertyPage page(IDD_PAGE1);
sh.AddPage(&page);
sh.DoModal();
return TRUE;
}
} myapp;
OK, I'm not sure I recommend this to anyone, but I did find a way to modify the template, finally. I had to use VirtualProtect to unlock the memory of the template.
for (int i = 0; i < m_pages.GetSize(); i++) {
CPropertyPage* pPage = GetPage(i);
PROPSHEETPAGE* tpsp = &pPage->m_psp;
const DLGTEMPLATE* pTemplate;
if (tpsp->dwFlags & PSP_DLGINDIRECT) {
pTemplate = tpsp->pResource;
} else {
HRSRC hResource = ::FindResource(tpsp->hInstance, tpsp->pszTemplate, RT_DIALOG);
if (hResource == NULL) return false;
HGLOBAL hTemplate = LoadResource(tpsp->hInstance, hResource);
if (hTemplate == NULL) return false;
pTemplate = (LPCDLGTEMPLATE)LockResource(hTemplate);
if (pTemplate == NULL) return false;
}
if (afxOccManager != NULL) {
DLGITEMTEMPLATE *pItem = _AfxFindFirstDlgItem(pTemplate);
DLGITEMTEMPLATE *pNextItem;
BOOL bDialogEx = IsDialogEx(pTemplate);
int iItem, iItems = DlgTemplateItemCount(pTemplate);
for (iItem = 0; iItem < iItems; iItem++) {
pNextItem = _AfxFindNextDlgItem(pItem, bDialogEx);
DWORD dwOldProtect, tp;
if (bDialogEx) {
_DialogSplitHelper::DLGITEMTEMPLATEEX *pItemEx = (_DialogSplitHelper::DLGITEMTEMPLATEEX *)pItem;
if (pItemEx->id == IDC_LIST1) {
if (VirtualProtect(&pItemEx->style, sizeof(pItemEx->style), PAGE_READWRITE, &dwOldProtect)) {
pItemEx->style |= LBS_OWNERDRAWFIXED;
VirtualProtect(&pItemEx->style, sizeof(pItemEx->style), dwOldProtect, &tp);
}
}
} else {
if (pItem->id == IDC_LIST1) {
if (VirtualProtect(&pItem->style, sizeof(pItem->style), PAGE_READWRITE, &dwOldProtect)) {
pItem->style |= LBS_OWNERDRAWFIXED;
VirtualProtect(&pItem->style, sizeof(pItem->style), dwOldProtect, &tp);
}
}
}
pItem = pNextItem;
}
}
}
return true;

Why app sometimes crashes when getting Icon from file?

I have functions to load and get Icon from files as follows:
std::map<wstring, HICON> m_map_icons;
void WindowSysTray::_loadIconFromFiles()
{
...
for (int i = 0; i < 3; ++i) {
wstring temp = path + trayList[i];
HICON hIcon = NULL;
Gdiplus::Bitmap bitmap(temp.c_str(), false);
bitmap.GetHICON(&hIcon);
pair<wstring, HICON> _pair = make_pair(trayList[i], hIcon);
m_map_icons.insert(_pair);
}
}
HICON WindowSysTray::getIconFromFile(const wchar_t* iconPath)
{
auto iter = m_map_icons.find(wstring(iconPath));
if (iter == m_map_icons.end()) {
return NULL;
}
else {
return iter->second; // ---Issue here---
}
}
...
hIcon = getIconFromFile(L"tray.png");
if (hIcon)
{
TrayIcon.SetIcon(hIcon);
}
...
When I invoke getIconFromFile function, it sometimes crashes while returning value at the end of the function:
return iter->second;
I verified and make sure that I loaded Icon before by invoking _loadIconFromFiles function.
Does anyone know what is the possible root cause of this issue?
m_map_icons.find() could go wrong. This might be the case if m_map_icons is empty. You can start WindowSysTray::getIconFromFile with a check:
if (m_map_icons.size() == 0) return 0;

How to get menu ID from HMENU?

I'm trying to override WM_HELP message for my dialog window when a user presses F1 key. The window has several buttons that display context menus via TrackPopupMenu, as well as the main menu (on top.) So there's more than just one menu in this window.
I can trap menu message as such when processing WM_HELP, but I need to know which context menu sent this message:
BOOL CMyDialog::OnHelpInfo(HELPINFO* pHelpInfo)
{
if(pHelpInfo->iContextType == HELPINFO_MENUITEM)
{
HMENU hMenu = (HMENU)pHelpInfo->hItemHandle;
//How to get menu ID from HMENU?
}
//...
}
So I need to find a way to get menu resource ID from HMENU -- this one that was used to create it:
Any idea how to do it?
You'll have to "somewhat bruteforce" it. You can approach it from the top-down. Make a function like this:
BOOL IsMenuItemIDInMenu(UINT nMenuID, UINT nMenuItemID)
{
//Checks if 'nMenuItemID' belongs to 'nMenuID'
BOOL bRes = FALSE;
if(nMenuID &&
nMenuItemID)
{
HMENU hMenu = ::LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(nMenuID));
if(hMenu)
{
//Look for it
bRes = __searchForMenuItem(hMenu, nMenuItemID);
//Free menu
::DestroyMenu(hMenu);
}
}
return bRes;
}
BOOL __searchForMenuItem(HMENU hMenu, UINT nMenuItemID)
{
ASSERT(hMenu);
int nCnt = ::GetMenuItemCount(hMenu);
if(nCnt != -1)
{
for(int i = 0; i < nCnt; i++)
{
//Is it a submenu
HMENU hSubMenu = ::GetSubMenu(hMenu, i);
if(!hSubMenu)
{
UINT nID = ::GetMenuItemID(hMenu, i);
if(nID != -1 &&
nID == nMenuItemID)
{
//Found it
return TRUE;
}
}
else
{
//Process submenu
if(__searchForMenuItem(hSubMenu, nMenuItemID))
{
//Found it in submenu
return TRUE;
}
}
}
}
return FALSE;
}
And then when you get a menu ID that was highlighted when F1 was pressed, see which of your menus it belongs to:
if(pHelpInfo->iContextType == HELPINFO_MENUITEM)
{
if(IsMenuItemIDInMenu(IDR_MENU_1, pHelpInfo->iCtrlId))
{
}
else if(IsMenuItemIDInMenu(IDR_MENU_2, pHelpInfo->iCtrlId))
{
}
}

RawInput loads 100% of my first CPU core and doesn't update properly

When I register RawInput, I check all the returns of the functions, everything is fine.However, when I update it it clogs up the performance on my 1st CPU core and it doesn't work properly(when I check if the 'M' button is pressed and have it create a message box when it is, it doesn't just trigger when I press 'M', but it triggers whenever I press anything or move the mouse.Also the message box doesn't come out, there's only a beep.)
Here's the code I use to initialize it:
const ushort usageTable[] =
{
InputDeviceUsage::UsageMouse,
InputDeviceUsage::UsageKeyboard,
InputDeviceUsage::UsageGamepad,
};
const ulong flagsTable[] =
{
mouseFlags,
keyboardFlags,
hidFlags
};
const List<SystemDevices>& systemDevices = EnumerateSystemDevices();
List<String> deviceNames;
List<InputDeviceInfo> deviceInfo;
for(uint i = 0; i < systemDevices.Size(); i++)
{
deviceNames.Add(GetDeviceName(systemDevices[i].hDevice));
deviceInfo.Add(GetDeviceInfo(systemDevices[i].hDevice));
InputDevice device =
{
InputDeviceUsagePage::UsagePageHID,
usageTable[deviceInfo[i].dwType],
flagsTable[deviceInfo[i].dwType],
window
};
RegisteredDevices.Add(device);
Devices[systemDevices[i].hDevice] = CreateDevice(deviceInfo[i].dwType);
Where List is the equivalent of std::vector<> and these are the typedefs and defines involved:
enum InputDeviceUsagePage
{
UsagePageHID = 0x01
};
enum InputDeviceUsage
{
UsageMouse = 0x02,
UsageKeyboard = 0x06,
UsageGamepad = 0x04
};
enum InputDeviceType
{
TypeMouse = RIM_TYPEMOUSE,
TypeKeyboard = RIM_TYPEKEYBOARD,
TypeHID = RIM_TYPEHID
};
enum InputDeviceChangeBehavior
{
Arrival = GIDC_ARRIVAL,
Removal = GIDC_REMOVAL
};
enum InputDeviceDataRequest
{
PreparseData = RIDI_PREPARSEDDATA,
Name = RIDI_DEVICENAME,
Info = RIDI_DEVICEINFO
};
And this is the Update function:
try
{
InputData data;
RawDevice::UpdateUnbuffered(reinterpret_cast<HRAWINPUT>(lparam), &data);
DevicePtr it = Devices[data.header.hDevice];
if(it == nullptr)
{
DevicePtr newDevice = CreateDevice(data.header.dwType);
Devices.Add(data.header.hDevice, newDevice);
if(data.header.hDevice != null)
{
it = newDevice;
}
}
DevicePtr device = it;
device->Read(data);
switch(data.header.dwType)
{
case InputDeviceType::TypeMouse:
{
const RawMouse& mouse = static_cast<RawMouse&>(*device);
//TODO: add event handling here
break;
}
case InputDeviceType::TypeKeyboard:
{
const RawKeyboard& keyboard = static_cast<RawKeyboard&>(*device);
//TODO: add event handling here
break;
}
case InputDeviceType::TypeHID:
{
const RawHID& hid = static_cast<RawHID&>(*device);
//TODO: add event handling here
break;
}
default:
{
}
}
return(exit_success);
}
catch(...)
{
return(DefWindowProc(window, message, wparam, lparam));
}
So for instance in the places that have //TODO: add event handling here I put:
case InputDeviceType::TypeKeyboard:
{
const RawKeyboard& keyboard = static_cast<RawKeyboard&>(*device);
if(keyboard.KeyDown('M'))
{
MessageBox(window, L"Pressed key is 'M'", L"Input event", MB_OK);
}
break;
}
I get a beep every time I press any key or any button on the mouse, not just M and also the message box doesn't show, the window just beeps.And the CPU core gets loaded to the maximum.This is the KeyDown() function:
const bool RawKeyboard::KeyDown(ushort key) const
{
if(_data.VKey == key && !(_data.Flags & KeyActions::KeyDown))
{
return(true);
}
{
return(false);
}
}
DevicePtr is basically a RawDevice* which contains a name and DeviceInfo and from RawDevice inherits RawMouse, RawKeyboard and RawHID, which in them have RAWMOUSE, RAWKEYBOARD, RAWHID members named _data.
EDIT: Just to add the place where Update is called:
case WM_INPUT:
{
return(_input.Update(_mainWindow.GetHandle(), message, wparam, lparam));
}
break;
EDIT2: Forgot to add the ReadUnbuffered method:
void RawDevice::UpdateUnbuffered(const HRAWINPUT rawInput, RAWINPUT* data)
{
wint64 size(sizeof(RAWINPUT));
boolresult = GetRawInputData(rawInput, RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
if(result == false)
{
throw RawInputException(GetLastError(), L"GetRawInputData()");
}
}
your message loop needs to process all messages in the queue before updating you application.
sounds like you are poping the first message switching to your app. filling the msg queue, getting one message, filling the queue some more... you get the point

When code accidently starts to work without a real change

I have run into similar situations before when my code is not working properly and on my quest to solve the problem I made some changes than comment those changes and boom it fixed the problem. All of sudden just a an 'edit' in the file somewhere has fixed the issue but there was no real change in the code. I ran into similar problem again and I am just wondering how does this happen?
void CDlgResizeHelper::Init(HWND hparent)
{
m_hParent = hparent;
m_CtrlsList.clear();
if (::IsWindow(m_hParent))
{
::GetWindowRect(m_hParent, m_OrigParentSize);
// get all child windows and store their original sizes and positions
HWND hCtrl = ::GetTopWindow(m_hParent);
while (hCtrl)
{
CtrlSize cs;
cs.hctrl = hCtrl;
::GetWindowRect(hCtrl, cs.orig_size);
::ScreenToClient(m_hParent, &cs.orig_size.TopLeft());
::ScreenToClient(m_hParent, &cs.orig_size.BottomRight());
// CString msg;
// msg.Format("Old Size: %d %d %d %d\r\n", cs.orig_size.left, cs.orig_size.top, cs.orig_size.right, cs.orig_size.bottom );
// TRACE( msg );
m_CtrlsList.push_back(cs);
hCtrl = ::GetNextWindow(hCtrl, GW_HWNDNEXT);
}
}
}
This class/function resizes controls based on the dialog size. It was working in debug version but the same code doesn't work (=resize properly) in release version. I made changes and added the three lines in the loop above for TRACE function. It starts to work properly in release version as well. Than I commented these lines, it still works in release build. I removed them and it doesn't work in release build anymore. I have to have these lines just commented present for release build to do the right thing. How can this be justified? What could really cause this 'edit' of file which is really no change in the real code fix the problem?
I also want to add that I have tried 'edit' or commented new code else where in the file that doesn't necessarily fixes the problem. I only need to have the commented code in the above function that would fix it.
Update Here is the complete class. I must say this class is available free somewhere on web and I am not the original author.
Init is called from the OnInitDialog of the dialog which needs resizing. It just stores the coordinates of all controls.
OnSize() actually does the resizing.
CDlgResizeHelper::CDlgResizeHelper()
{
}
void CDlgResizeHelper::Init(HWND hparent)
{
m_hParent = hparent;
m_CtrlsList.clear();
if (::IsWindow(m_hParent))
{
::GetWindowRect(m_hParent, m_OrigParentSize);
// get all child windows and store their original sizes and positions
HWND hCtrl = ::GetTopWindow(m_hParent);
while (hCtrl)
{
CtrlSize cs;
cs.hctrl = hCtrl;
::GetWindowRect(hCtrl, cs.orig_size);
::ScreenToClient(m_hParent, &cs.orig_size.TopLeft());
::ScreenToClient(m_hParent, &cs.orig_size.BottomRight());
CString msg;
msg.Format("Old Size: %d %d %d %d\r\n", cs.orig_size.left, cs.orig_size.top, cs.orig_size.right, cs.orig_size.bottom );
Sleep( 50 );
m_CtrlsList.push_back(cs);
hCtrl = ::GetNextWindow(hCtrl, GW_HWNDNEXT);
}
}
}
void CDlgResizeHelper::Remove(HWND hwnd)
{
CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
{
if (it->hctrl == hwnd)
{
m_CtrlsList.erase(it);
return;
}
}
}
void CDlgResizeHelper::Update(HWND hwnd)
{
if (m_hParent && hwnd)
{
CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
{
if (it->hctrl == hwnd)
{
::GetWindowRect(hwnd, &(it->orig_size));
::ScreenToClient(m_hParent, &(it->orig_size.TopLeft()));
::ScreenToClient(m_hParent, &(it->orig_size.BottomRight()));
}
}
}
}
void CDlgResizeHelper::Add(HWND hwnd)
{
if (m_hParent && hwnd)
{
CtrlSize cs;
cs.hctrl = hwnd;
::GetWindowRect(hwnd, cs.orig_size);
::ScreenToClient(m_hParent, &cs.orig_size.TopLeft());
::ScreenToClient(m_hParent, &cs.orig_size.BottomRight());
m_CtrlsList.push_back(cs);
}
}
void CDlgResizeHelper::OnSize()
{
if (::IsWindow(m_hParent))
{
CRect currparentsize;
::GetWindowRect(m_hParent, currparentsize);
double xratio = ((double) currparentsize.Width()) / m_OrigParentSize.Width();
double yratio = ((double) currparentsize.Height()) / m_OrigParentSize.Height();
HDWP hdwp;
hdwp = BeginDeferWindowPos((int)m_CtrlsList.size());
// resize child windows according to their fix attributes
CtrlList::const_iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
{
CRect currctrlsize;
HorizFix horiz_fix = it->horiz_fix;
VertFix vert_fix = it->vert_fix;
if (horiz_fix & LEFT)
currctrlsize.left = it->orig_size.left;
else
currctrlsize.left = (LONG)( ((horiz_fix & WIDTH) && (horiz_fix & RIGHT)) ? (it->orig_size.left + currparentsize.Width() - m_OrigParentSize.Width()) : (it->orig_size.left * xratio));
if (horiz_fix & RIGHT)
currctrlsize.right = it->orig_size.right + currparentsize.Width() - m_OrigParentSize.Width();
else
currctrlsize.right = (LONG)((horiz_fix & WIDTH) ? (currctrlsize.left + it->orig_size.Width()) : (it->orig_size.right * xratio));
if (vert_fix & TOP)
currctrlsize.top = it->orig_size.top;
else
currctrlsize.top = (LONG)(((vert_fix & HEIGHT) && (vert_fix & BOTTOM)) ? (it->orig_size.top + currparentsize.Height() - m_OrigParentSize.Height()) : (it->orig_size.top * yratio));
if (vert_fix & BOTTOM)
currctrlsize.bottom = it->orig_size.bottom + currparentsize.Height() - m_OrigParentSize.Height();
else
currctrlsize.bottom = (LONG)((vert_fix & HEIGHT) ? (currctrlsize.top + it->orig_size.Height()) : (it->orig_size.bottom * yratio));
UINT flags = SWP_NOZORDER;
if (! it->resize)
flags |= SWP_NOSIZE;
hdwp = ::DeferWindowPos(hdwp, it->hctrl, NULL, currctrlsize.left, currctrlsize.top, (it->resize)? currctrlsize.Width() : 0, (it->resize)? currctrlsize.Height() : 0, flags);
if (hdwp == NULL)
return;
} //end for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
EndDeferWindowPos(hdwp);
} //end if (::IsWindow(m_hParent))
}
BOOL CDlgResizeHelper::Fix(HWND a_hCtrl, HorizFix a_hFix, VertFix a_vFix, bool resize /= true/)
{
CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
{
if (it->hctrl == a_hCtrl)
{
it->horiz_fix = a_hFix;
it->vert_fix = a_vFix;
it->resize = resize;
return TRUE;
}
}
return FALSE;
}
BOOL CDlgResizeHelper::Fix(int a_itemId, HorizFix a_hFix, VertFix a_vFix, bool resize /= true/)
{
return Fix(::GetDlgItem(m_hParent, a_itemId), a_hFix, a_vFix, resize);
}
BOOL CDlgResizeHelper::Fix(HorizFix a_hFix, VertFix a_vFix, bool resize /= true/)
{
CtrlList::iterator it;
for(it = m_CtrlsList.begin(); it!=m_CtrlsList.end(); ++it)
{
it->horiz_fix = a_hFix;
it->vert_fix = a_vFix;
it->resize = resize;
}
return TRUE;
}
UINT CDlgResizeHelper::Fix(LPCTSTR a_pszClassName, HorizFix a_hFix, VertFix a_vFix, bool resize /= true/)
{
char cn_buf[200];
memset(cn_buf, 0, 200);
UINT cnt = 0;
CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it!= m_CtrlsList.end(); ++it)
{
::GetClassName(it->hctrl, cn_buf, sizeof(cn_buf));
if (strcmp(cn_buf, a_pszClassName) == 0)
{
cnt++;
it->horiz_fix = a_hFix;
it->vert_fix = a_vFix;
it->resize = resize;
}
}
return cnt;
}
This sounds like you have uninitialized variable used somewhere. It can get different values depending on build mode and it just so happens that it is assigned something harmless in debug.
Try running CppCheck application against your code. Won't hurt anyway.