Visual C++: Why Watch window shows 'unused' for a HWND variable?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1

Thread: Visual C++: Why Watch window shows 'unused' for a HWND variable?

Threaded View

  1. #1
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    7,994

    Visual C++: Why Watch window shows 'unused' for a HWND variable?

    Q: When expand a variable of type HWND in Watch, QuickWatch or Variables window, the following is shown: unused - CXX0030: Error: expression cannot be evaluated.



    What 'unused' means? Is it an error in program?

    A: No, it isn't a programming error.
    We can find in WINDEF.H
    Code:
    DECLARE_HANDLE            (HWND);
    DECLARE_HANDLE is defined as
    Code:
    typedef void *PVOID;
    //...
    #ifdef STRICT
    typedef void *HANDLE;
    #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
    #else
    typedef PVOID HANDLE;
    #define DECLARE_HANDLE(name) typedef HANDLE name
    #endif
    typedef HANDLE *PHANDLE;
    There are two situations:
    1. If STRICT is not defined, HWND is an alias of void*.
      This case, if let's say a HWND type is required as a function parameter, we can easily make a mistake and pass some other handle type (e.g. HBRUSH which is also void*) or any other pointer type.
      That leads in run-time errors and program malfunction.
    2. If STRICT is defined, then STRICT type checking is performed.
      After preprocessing phase, the above code becomes something like:
      Code:
         struct HWND__ 
         {
            int unused;
         };
         typedef struct HWND__ *HWND;
      Now, HWND is of type pointer to a structure (HWND__ *) and, if we replace it by mistake with HBRUSH (of type HBRUSH__*) the compiler raises an error, avoiding further run-time troubles.
      Example
      Code:
         HBRUSH hBrush = ::CreateSolidBrush(RGB(0, 0, 255));
         // ...
         // Stupid but possible mistake
         ::SetForegroundWindow(hBrush); 
         // Error: cannot convert parameter 1 from 'struct HBRUSH__ *' to 'struct HWND__ *'

    Notes
    1. There is a bunch of other handle types defined in the same manner (HBITMAP, HINSTANCE, etc). See WINDEF.H header file.
    2. In Windows SDK, STRICT is defined by default. If, for some reason you don't want it, you have to add NO_STRICT to preprocessor definitions.
    3. The C standard states the following: if the struct-declaration-list contains no named members, the behavior is undefined, then C compiler from Visual Studio gives an error if we have an empty structure: error C2016: C requires that a struct or union has at least one member.
      For this reason, HWND__ and the other similar structures have a dummy member, int unused.

    Resources

    Credits
    • Thanks Viorel for suggesting note #3!
    Last edited by ovidiucucu; November 4th, 2011 at 02:08 PM.
    Ovidiu Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center