Moe45673
Moe45673

Reputation: 884

Getting Desktop Resolution in MFC C++

I have inherited some partially developed 10 year old code that was written in MFC C++. I've been tasked with updating and finishing the app.

In the CDialogChild class, it looks like this in the .h file:

private:
static const int m_iDefaultDesktopSizeX = 1024;

static const int m_iDefaultDesktopSizeY = 740;

I'm still trying to figure out the code and the logic behind it, but I decided to dynamically get the resolution. I removed the "static" keyword from the .h as well as the magic numbers, and then I attempted to define them in the initialisation list in the constructor:

CDialogChild::CDialogChild(CWnd* pParent /*=NULL*/)
: CDialog(CDialogChild::IDD, pParent) , //more variables,
m_iDefaultDesktopSizeX(GetSystemMetrics(SM_CXSCREEN)), m_iDefaultDesktopSizeY(GetSystemMetrics(SM_CYSCREEN))
{
//...
}

My resolution is 1366x768, the numbers I get in the Visual Studio 2013 debugger vary, from "unable to access memory" to numbers in the millions.

I then decided to attempt to initialize them in the constructor and not the initialisation list. I removed the "const" keyword in the header from both variables and then figured I would print to the debug output their values. This is my code (I get that it's not so elegant but still figuring out the MFC conventions):

#ifdef UNICODE
typedef std::wstringstream tstringstream;
#else
typedef std::stringstream tstringstream;
#endif

m_iDefaultDesktopSizeX = GetSystemMetrics(SM_CXSCREEN);
m_iDefaultDesktopSizeY = GetSystemMetrics(SM_CYSCREEN);    

#ifdef OUTPUT_DEBUG_STRING
    tstringstream ss1;
    tstringstream ss2;

    ss1 << m_iDefaultDesktopSizeX;
    //stream >> sizeX;

    ss2 << m_iDefaultDesktopSizeY;

    LPTSTR dest = _T("m_iDefaultDesktopSizeX = ");
    LPTSTR src1 = _T("");
    LPTSTR src2 = _T("");

    ss1 >> src1;
    ss2 >> src2;

    // 1000 is a magic number
    StringCchCat(dest, 1000, src1);
    StringCchCat(dest, 1000, _T(" and m_iDefaultDesktopSizeY = "));
    StringCchCat(dest, 1000, src2);
    OutputDebugString(dest);
#endif

When I run it, an exception is thrown on the "ss2 >> src2" saying access violation writing to [hex address]

So, what is going on and what more info should I provide? The problem I am getting is during my troubleshooting of another problem, so help with either or both would be awesome!

EDIT

Thanks to Mark's comment, I changed the initialization of all the LPTSTR variables to be "new TCHAR()", which fixed that particular issue. I was able to run the string in the debug output, which showed the correct resolution (even though it's wrong in the VS Debugger itself), so thanks a lot! This works even when I put the variables back in the Constructor initialization list and make them "const" again :)

However, I now get a new error. While this is ultimately not an issue that it's happening in this #ifdef block, the error I am now getting might pop up in other code I write.

The code:

tstringstream ss1;
tstringstream ss2;

ss1 << m_iDefaultDesktopSizeX;
//stream >> sizeX;

ss2 << m_iDefaultDesktopSizeY;

LPTSTR dest = new TCHAR();
StringCchCat(dest, 300, _T("\nm_iDefaultDesktopSizeX = "));
LPTSTR src1 = new TCHAR();
LPTSTR src2 = new TCHAR();

ss1 >> src1;
ss2 >> src2;


StringCchCat(dest, 300, src1);
StringCchCat(dest, 300, _T(" and m_iDefaultDesktopSizeY = "));
StringCchCat(dest, 300, src2);
OutputDebugString(dest);

//error happens on the line below this one!!!!
delete dest;
dest = 0;
delete  src1;
src1 = 0;
delete  src2;
src2 = 0;

The error occurs when the runtime reaches the delete commands and it is that the .exe file has triggered a breakpoint.

Upvotes: 1

Views: 164

Answers (1)

user1610015
user1610015

Reputation: 6678

The error is most likely caused by the buffer overruns in your code such as the following:

LPTSTR dest = new TCHAR();
StringCchCat(dest, 300, _T("\nm_iDefaultDesktopSizeX = "));

The first line allocates a single character, then on the second line you write about 20-30 characters to it.

Don't bother with raw string pointers, just use CString or std::wstring:

tstringstream ss1;
tstringstream ss2;

ss1 << m_iDefaultDesktopSizeX;
ss2 << m_iDefaultDesktopSizeY;

CString dest = _T("\nm_iDefaultDesktopSizeX = ");
dest += ss1.str().c_str();
dest += _T(" and m_iDefaultDesktopSizeY = ");
dest += ss2.str().c_str();

OutputDebugString(dest);

Upvotes: 4

Related Questions