Midas
Midas

Reputation: 7131

SetProp problem

Can anybody tell me why the following code doesn't work? I don't get any compiler errors.

short value = 10;
SetProp(hCtl, "value", (short*) value);

Upvotes: 1

Views: 2457

Answers (2)

Davus Crucis
Davus Crucis

Reputation: 31

I would create the short on the heap, so that it continues to exist, or perhaps make it global, which is perhaps what you did. Also the cast for the short address needs to be void *, or HANDLE.

Upvotes: 0

Tadmas
Tadmas

Reputation: 6368

The third parameter is typed as a HANDLE, so IMO to meet the explicit contract of the function you should save the property as a HANDLE by allocating a HGLOBAL memory block. However, as noted in the comments below, MSDN states that any value can be specified, and indeed when I try it on Windows 7 using...

SetProp(hWnd, _T("TestProp"), (HANDLE)(10)); // or (HANDLE)(short*)(10)
...
(short)GetProp(hWnd, _T("TestProp"));

... I get back 10 from GetProp. I suspect somewhere between your SetProp and GetProp one of two things happens: (1) the value of hWnd is different -- you're checking a different window or (2) a timing issue -- the property hasn't been set yet or had been removed.


If you wanted to use an HGLOBAL instead to follow the specific types of the function signature, you can follow this example in MSDN.

Even though a HANDLE is just a pointer, it's a specific data type that is allocated by calls into the Windows API. Lots of things have handles: icons, cursors, files, ... Unless the documentation explicitly states otherwise, to use a blob of data such as a short when the function calls for a HANDLE, you need a memory handle (an HGLOBAL).

The sample code linked above copies data as a string, but you can instead set it as another data type:

// TODO: Add error handling
hMem = GlobalAlloc(GPTR, sizeof(short));
lpMem = GlobalLock(hMem);
if (lpMem != NULL)
{
    *((short*)lpMem) = 10;
    GlobalUnlock(hMem);
}

To read it back, when you GetProp to get the HANDLE you must lock it to read the memory:

// TODO: Add error handling
short val;
hMem = (HGLOBAL)GetProp(hwnd, ...); 
if (hMem)
{
    lpMem = GlobalLock(hMem);
    if (lpMem)
    {
        val = *((short*)lpMem);
    }
}

Upvotes: 2

Related Questions