|
|
|
|
|
|
|
|
Freeing up DLLs, avoiding suspend mode, and listbox tricks (continued)
As the saying goes, it's a feature not a bug. In fact, this "feature" is present in all releases of Windows CE, Windows NT, Windows 95 and Windows 98. The problem is that, by default, a listbox does not update its horizontal extent as strings are added and removed. The horizontal extent is simply the logical unit width of a string when it's drawn with a particular font. Fortunately, if you manually update a listbox with the maximum horizontal extent of the strings it currently contains, the horizontal scrollbar will magically appear. Here's come code that shows how to do this:
/*
This function updates the horizontal extent for hwndList so that a horizontal scroll bar will show up and work properly.
*/
void UpdateHorzExtent(HWND hwndList)
{
HDC hdc = GetDC(hwndList);
HFONT hFont = (HFONT)SendMessage(hwndList, WM_GETFONT, 0, 0);
HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);
int iLongestExtent = 0;
int iCount = ListBox_GetCount(hwndList);
TCHAR chBuf[MAX_STRING_LENGTH];
for ( int i = 0; i < iCount; i++ )
{
ListBox_GetText(hwndList, i, chBuf);
SIZE size;
GetTextExtentPoint32(hdc, chBuf, _tcslen(chBuf), &size);
size.cx += 6; // fudge factor
if ( size.cx > iLongestExtent )
iLongestExtent = size.cx;
}
ListBox_SetHorizontalExtent(hwndList, iLongestExtent);
SelectObject(hdc, hOldFont);
ReleaseDC(hwndList, hdc);
}
|
The first thing we do is get an HDC for the window and select the current font into it. We then walk through the strings in the listbox, calculate the size of each with the GetTextExtentPoint32 API, and record the maximum. A "fudge factor" of six units is added to the width to account for a small right hand margin between the end of the text and the edge of the listbox. After we drop out of the loop, the listbox is updated with a call to ListBox_SetHorizontalExtent and we release the HDC after resetting the original font handle.
There are a couple of drawbacks to UpdateHorzExtent. It's up to you, the developer, to make sure it gets called after each string is inserted or deleted. This could be automated by subclassing the listbox or using a C++ class wrapper. The other problem is that the code assumes that no string in the listbox is bigger than the MAX_STRING_LENGTH constant. An industrial strength application would probably want to dynamically allocate the memory to make sure that chBuf never overflows.
I'm trying to copy some text to the clipboard, but it doesn't seem to work. How come? Edit controls have built-in capability to perform cut, copy, and paste actions by responding to the WM_CUT, WM_COPY, and WM_PASTE messages, respectively, but it's also possible to manually put data on the clipboard and retrieve it. Unfortunately, the Windows CE implementation of the clipboard APIs has some quirks.
Although the documentation states that the OpenClipboard API allows a NULL parameter, this doesn't work for Windows CE. The call, and all subsequent clipboard calls, will still return TRUE, but the data will not end up on the clipboard. Instead, Windows CE requires a valid window handle for the OpenClipboard call and, additionally, the window must have been created by the process calling OpenClipboard. If the window was created by another process, you can put data on the clipboard, but any paste operation to remove it will cause a series of access violation exceptions and require a warm boot of the device.
|
|
|
|
|
|
|
|
|
|
|