Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Memory read error on Win2K, but not on XP

Memory read error on Win2K, but not on XP

Scheduled Pinned Locked Moved C / C++ / MFC
graphicscomperformancehelp
11 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Joe Smith IX

    Hi, I use a CButton-derived ThemeButton (http://www.codeproject.com/buttonctrl/WowButtons.asp[^]) in my project. It works on XP, but crashes on Windows 2000 with the following error: "The instruction at '0x00000000' referenced memory at '0x00000000'. The memory could not be 'read'." I traced it and it happened in the following function:

    void ThemeButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
    HDC hDC = lpDrawItemStruct->hDC;
    CDC* pDC = CDC::FromHandle(hDC);
    CRect rc = lpDrawItemStruct->rcItem;
    CString sText (_T(""));

    ::CopyRect(&m_pGDSData->rcClip,rc);
    ::CopyRect(&m_pGDSData->rcDest,rc);
    m_pGDSData->hDC = hDC;

    if( !(lpDrawItemStruct->itemState & (ODS_DISABLED|ODS_SELECTED)) )
    {
    if( !m_tracking )
    {
    if( lpDrawItemStruct->itemState & ODS_FOCUS )
    ::CopyRect(&m_pGDSData->rcSrc,m_rcDefault);
    else
    ::CopyRect(&m_pGDSData->rcSrc,m_rcNormal);
    }
    else
    ::CopyRect(&m_pGDSData->rcSrc,m_rcHot);
    }
    else
    {
    if( lpDrawItemStruct->itemState & ODS_SELECTED )
    ::CopyRect(&m_pGDSData->rcSrc,m_rcPressed);
    if( lpDrawItemStruct->itemState & ODS_DISABLED )
    ::CopyRect(&m_pGDSData->rcSrc,m_rcDissabled);
    }

    (*GdiDrawStreamFunc)(hDC,sizeof(GdiDrawStreamStruct),m_pGDSData); // THIS CRASHES ON WIN2K

    ...
    }

    BOOL ThemeButton::InitControl(...)
    {
    ...
    m_pGDSData = new GdiDrawStreamStruct;
    ZeroMemory(m_pGDSData,sizeof(GdiDrawStreamStruct));

    m_pGDSData->... = ...;
    m_pGDSData->... = ...;
    ...
    }

    in the .h file:

    PGdiDrawStreamStruct m_pGDSData;

    typedef struct GdiDrawStreamStruct_tag
    {
    DWORD signature; // = 0x44727753;//"Swrd"
    DWORD reserved; // Zero value.
    HDC hDC; // handle to the device object of windiw to draw.
    RECT rcDest; // desination rect of window to draw.
    DWORD unknown1; // must be 1.
    HBITMAP hImage; // handle to the specia bitmap image.
    DWORD unknown2; // must be 9.
    RECT rcClip; // desination rect of window to draw.
    RECT rcSrc; // source rect of bitmap to draw.
    DWORD drawOption; // option flag for drawing image.
    DWORD leftArcValue; // arc value of left side.
    DWORD

    M Offline
    M Offline
    Mark Salsbery
    wrote on last edited by
    #2

    Is GdiDrawStreamFunc NULL?

    Mark Salsbery Microsoft MVP - Visual C++ :java:

    J 1 Reply Last reply
    0
    • M Mark Salsbery

      Is GdiDrawStreamFunc NULL?

      Mark Salsbery Microsoft MVP - Visual C++ :java:

      J Offline
      J Offline
      Joe Smith IX
      wrote on last edited by
      #3

      No. typedef BOOL (__stdcall *GdiDrawStream)(HDC hDC, DWORD dwStructSize,PGdiDrawStreamStruct pStream); static GdiDrawStream GdiDrawStreamFunc = (GdiDrawStream)GetProcAddress(GetModuleHandle(_T("GDI32.DLL")),_T("GdiDrawStream\0"));

      M R 2 Replies Last reply
      0
      • J Joe Smith IX

        No. typedef BOOL (__stdcall *GdiDrawStream)(HDC hDC, DWORD dwStructSize,PGdiDrawStreamStruct pStream); static GdiDrawStream GdiDrawStreamFunc = (GdiDrawStream)GetProcAddress(GetModuleHandle(_T("GDI32.DLL")),_T("GdiDrawStream\0"));

        M Offline
        M Offline
        Mark Salsbery
        wrote on last edited by
        #4

        Right, I've seen the code.  The exception kind of indicated a NULL function pointer. I imagine it's using visual styles available only on XP+ Visual Styles[^] Mark

        Mark Salsbery Microsoft MVP - Visual C++ :java:

        J 1 Reply Last reply
        0
        • M Mark Salsbery

          Right, I've seen the code.  The exception kind of indicated a NULL function pointer. I imagine it's using visual styles available only on XP+ Visual Styles[^] Mark

          Mark Salsbery Microsoft MVP - Visual C++ :java:

          J Offline
          J Offline
          Joe Smith IX
          wrote on last edited by
          #5

          Does this mean there is ABSOLUTELY no way this code could run in Win2K? (If you see header part on http://www.codeproject.com/buttonctrl/WowButtons.asp[^], you can see that it SHOULD run even on Win95/NT4. Or I shouldn't rely on this information?) If that so, is there any way I can differentiate which code is executed depending on the windows version? (The declaration is in the .h file, not in .cpp) Can I do something like: (pseudo-code) in the .h file

          class CMyDlg : public CDialog
          {
          ...
          // Dialog Data
          //{{AFX_DATA(CLoginDlg)
          enum { IDD = IDD_MYDLG };
          if(WindowsVersion>=XP)
          ThemeButton m_btn1;
          else
          CButton m_btn1;
          ...
          //}}AFX_DATA
          ...
          }

          M 1 Reply Last reply
          0
          • J Joe Smith IX

            No. typedef BOOL (__stdcall *GdiDrawStream)(HDC hDC, DWORD dwStructSize,PGdiDrawStreamStruct pStream); static GdiDrawStream GdiDrawStreamFunc = (GdiDrawStream)GetProcAddress(GetModuleHandle(_T("GDI32.DLL")),_T("GdiDrawStream\0"));

            R Offline
            R Offline
            Rick York
            wrote on last edited by
            #6

            It looks like you are initializing a static variable with the result from GetProcAddress and that's not a recommended practice because the application is not fully initialized. You can find some interesting blog entries about these issues on this page : http://blogs.msdn.com/mgrier/archive/2005/06.aspx[^] It is best to initialize the function pointer to NULL and make the call to GetProcAddress later during "real" application execution.

            J 1 Reply Last reply
            0
            • J Joe Smith IX

              Does this mean there is ABSOLUTELY no way this code could run in Win2K? (If you see header part on http://www.codeproject.com/buttonctrl/WowButtons.asp[^], you can see that it SHOULD run even on Win95/NT4. Or I shouldn't rely on this information?) If that so, is there any way I can differentiate which code is executed depending on the windows version? (The declaration is in the .h file, not in .cpp) Can I do something like: (pseudo-code) in the .h file

              class CMyDlg : public CDialog
              {
              ...
              // Dialog Data
              //{{AFX_DATA(CLoginDlg)
              enum { IDD = IDD_MYDLG };
              if(WindowsVersion>=XP)
              ThemeButton m_btn1;
              else
              CButton m_btn1;
              ...
              //}}AFX_DATA
              ...
              }

              M Offline
              M Offline
              Mark Salsbery
              wrote on last edited by
              #7

              I'm not sure why my posts got voted 5....I haven't helped any :) If I had documentation on this "GdiDrawStream" function in GDI32.DLL it would be much easier to give a definite answer. If this is something that is only supported with the new visual styles, and you want to use it in Windows 2000, then I would recommend modifying the button class instead of checking the OS version in the class using the buttons (like you've shown).   That would encapsulate the OS versioning stuff nicely so you wouldn't need to use different button classes in your dialogs. The ThemeButton class is already derived from CButton, so it should be pretty easy to modify the class - if the OS version is < XP just use the default CButton implementation. Mark

              Mark Salsbery Microsoft MVP - Visual C++ :java:

              L J 2 Replies Last reply
              0
              • M Mark Salsbery

                I'm not sure why my posts got voted 5....I haven't helped any :) If I had documentation on this "GdiDrawStream" function in GDI32.DLL it would be much easier to give a definite answer. If this is something that is only supported with the new visual styles, and you want to use it in Windows 2000, then I would recommend modifying the button class instead of checking the OS version in the class using the buttons (like you've shown).   That would encapsulate the OS versioning stuff nicely so you wouldn't need to use different button classes in your dialogs. The ThemeButton class is already derived from CButton, so it should be pretty easy to modify the class - if the OS version is < XP just use the default CButton implementation. Mark

                Mark Salsbery Microsoft MVP - Visual C++ :java:

                L Offline
                L Offline
                led mike
                wrote on last edited by
                #8

                Mark Salsbery wrote:

                I'm not sure why my posts got voted 5....I haven't helped any

                Maybe you are spurring visions of Filet-O-Fish

                M 1 Reply Last reply
                0
                • L led mike

                  Mark Salsbery wrote:

                  I'm not sure why my posts got voted 5....I haven't helped any

                  Maybe you are spurring visions of Filet-O-Fish

                  M Offline
                  M Offline
                  Mark Salsbery
                  wrote on last edited by
                  #9

                  <homersimpsonvoice> mmmmm....filet-o-fish...</homersimpsonvoice>

                  Mark Salsbery Microsoft MVP - Visual C++ :java:

                  1 Reply Last reply
                  0
                  • M Mark Salsbery

                    I'm not sure why my posts got voted 5....I haven't helped any :) If I had documentation on this "GdiDrawStream" function in GDI32.DLL it would be much easier to give a definite answer. If this is something that is only supported with the new visual styles, and you want to use it in Windows 2000, then I would recommend modifying the button class instead of checking the OS version in the class using the buttons (like you've shown).   That would encapsulate the OS versioning stuff nicely so you wouldn't need to use different button classes in your dialogs. The ThemeButton class is already derived from CButton, so it should be pretty easy to modify the class - if the OS version is < XP just use the default CButton implementation. Mark

                    Mark Salsbery Microsoft MVP - Visual C++ :java:

                    J Offline
                    J Offline
                    Joe Smith IX
                    wrote on last edited by
                    #10

                    Mark Salsbery wrote:

                    I'm not sure why my posts got voted 5....I haven't helped any

                    :) Sure you've helped (maybe just a little bit by pointing me to the right direction). I generally vote either 1 or 5. I have difficulty deciding in between :) The msdn page you referred states that the visual aspect is provided by the new ComCtl32.dll and UxTheme.dll in Windows XP. Can I include these 2 dll's from my XP, then load them in run time if the OS is less than XP? I'll poke around some more. If I ended up giving up, I'll just check the OS version in the ThemeButton class like you suggested. Thanks.

                    1 Reply Last reply
                    0
                    • R Rick York

                      It looks like you are initializing a static variable with the result from GetProcAddress and that's not a recommended practice because the application is not fully initialized. You can find some interesting blog entries about these issues on this page : http://blogs.msdn.com/mgrier/archive/2005/06.aspx[^] It is best to initialize the function pointer to NULL and make the call to GetProcAddress later during "real" application execution.

                      J Offline
                      J Offline
                      Joe Smith IX
                      wrote on last edited by
                      #11

                      But the code runs fine on XP... I don't have Win2K box with me right now, so I'll try your idea tomorrow. Thanks.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups