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 Offline
    J Offline
    Joe Smith IX
    wrote on last edited by
    #1

    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 1 Reply Last reply
    0
    • 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