Determining which version of Windows the program is running
BOOL InWinNT() //test for NT
Translating the value returned by GetLastError() into a readable string
BOOL GetFormattedError(LPTSTR dest,int size)
Clearing the screen in text mode
The following code will clear the screen in text mode.
#include <windows.h>
/* Standard error macro for reporting API errors */
#define PERR(bSuccess, api)
void cls( HANDLE hConsole )
/* Home the cursor here */
BOOL bSuccess;
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
DWORD dwConSize; /* number of character cells in the current buffer */
/* get the number of character cells in the current buffer */
bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi );
PERR( bSuccess, "GetConsoleScreenBufferInfo" );
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
/* fill the entire screen with blanks */
bSuccess = FillConsoleOutputCharacter( hConsole, (TCHAR) ' ',
dwConSize, coordScreen, &cCharsWritten );
PERR( bSuccess, "FillConsoleOutputCharacter" );
/* get the current text attribute */
bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi );
PERR( bSuccess, "ConsoleScreenBufferInfo" );
/* now set the buffer's attributes accordingly */
bSuccess = FillConsoleOutputAttribute(hConsole, csbi.wAttributes,
dwConSize, coordScreen, &cCharsWritten );
PERR( bSuccess, "FillConsoleOutputAttribute" );
/* put the cursor at (0, 0) */
bSuccess = SetConsoleCursorPosition( hConsole, coordScreen );
PERR( bSuccess, "SetConsoleCursorPosition" );
return;
This function can be called like this:
cls(GetStdHandle(STD_OUTPUT_HANDLE));
The library TCCONIO.LIB contains many other functions for text manipulation using the console interface. The corresponding header file is TCCONIO.H, which is automatically included when you include conio.h
This library was contributed by Daniel Guerrero ([email protected])
Getting a pointer to the stack
To get a pointer to the stack, use the following code:
far MyFunction()
NOTE: This pointer will not be valid when the function is exited, since the stack contents will change.
Disabling the screen saver from a program
Under Windows NT, you can disable the screen saver from your application code. To detect if the screen saver is enabled, use this:
SystemParametersInfo( SPI_GETSCREENSAVEACTIVE,
0,
pvParam,
0
);
On return, the parameter pvParam will point to TRUE if the screen saver setting is enabled in the system control panel applet and FALSE if the screen saver setting is not enabled.
To disable the screen saver setting, call SystemParametersInfo() with this:
SystemParametersInfo( SPI_SETSCREENSAVEACTIVE,
FALSE,
0,
SPIF_SENDWININICHANGE
);
Drawing a gradient background
You can draw a smooth gradient background using the following code:
void DrawBackgroundPattern(HWND hWnd)
// Give back the DC.
ReleaseDC(hWnd, hDC);
Capturing and printing the contents of a entire window
// Return a HDC for the default printer.
HDC GetPrinterDC(void)
// Create a copy of the current system palette.
HPALETTE GetSystemPalette()
// Allocate memory for the palette.
lpLogPal = GlobalAlloc(GPTR, sizeof(LOGPALETTE) + 256 *
sizeof(PALETTEENTRY));
if (!hLogPal)
return NULL;
// Initialize.
lpLogPal->palVersion = 0x300;
lpLogPal->palNumEntries = 256;
// Copy the current system palette into the logical palette.
GetSystemPaletteEntries(hDC, 0, 256,
(LPPALETTEENTRY) (lpLogPal->palPalEntry));
// Create the palette.
hPal = CreatePalette(lpLogPal);
// Clean up.
GlobalFree(lpLogPal);
ReleaseDC(NULL, hDC);
return hPal;
// Create a 24-bit-per-pixel surface.
HBITMAP Create24BPPDIBSection(HDC hDC, int iWidth, int iHeight)
// Print the entire contents (including the non-client area) of
// the specified window to the default printer.
BOOL PrintWindowToDC(HWND hWnd)
// Prepare the surface for drawing.
hdcMemory = CreateCompatibleDC(hdcWindow);
SelectObject(hdcMemory, hbm);
// Get the current system palette.
hPal = GetSystemPalette(); // If a palette was returned.
if (hPal)
// Copy the window contents to the memory surface.
BitBlt(hdcMemory, 0, 0, rc.right, rc.bottom,
hdcWindow, 0, 0, SRCCOPY);
// Prepare the DOCINFO.
ZeroMemory(&di, sizeof(di));
di.cbSize = sizeof(di);
di.lpszDocName = "Window Contents"; // Initialize the print job.
if (StartDoc(hdcPrinter, &di) > 0)
// Let the driver know the document is done.
EndDoc(hdcPrinter);
}
// Clean up the objects you created.
DeleteDC(hdcPrinter);
DeleteDC(hdcMemory);
ReleaseDC(hWnd, hdcWindow);
DeleteObject(hbm);
if (hPal)
DeleteObject(hPal);
Centering a dialog box in the screen
Use the following code:
Determining the number of visible items in a list box
In a list box, if the number of lines is greater than the number of lines in the list box, some of them will be hidden. In addition, it could be that the list box is an owner draw list box, making the height of each line a variable quantity. Here is a code snippet that will handle all cases, even when all of the items of the list box are visible, and some white space is left at the bottom.
The basic idea is to subtract each line height from the total height of the client area of the list box.
Int ntop, nCount, nRectheight, nVisibleItems;
RECT rc, itemrect;
// First, get the index of the first visible item.
ntop = SendMessage(hwndList, LB_GETTOPINDEX, 0, 0);
// Then get the number of items in the list box.
nCount = SendMessage(hwndList, LB_GETCOUNT, 0, 0);
// Get the list box rectangle.
GetClientRect(hwndList, &rc);
// Get the height of the list box's client area.
nRectheight = rc.bottom - rc.top;
// This counter will hold the number of visible items.
nVisibleItems = 0;
// Loop until the bottom of the list box.
// or the last item has been reached.
While ((nRectheight > 0) && (ntop < nCount))
Starting a non-modal dialog box
Non-modal dialog boxes behave as independent top level windows. They can be started using the CreateDialog function.
HWND CreateDialog( HINSTANCE hInstance, // handle to application instance
LPCTSTR lpTemplate, // Identifies dialog box template name.
HWND hWndParent, // Handle to owner window.
DLGPROC lpDialogFunc // Pointer to dialog box procedure.
Non-modal dialog boxes should be used with care, since they are equivalent to starting another thread of execution. In addition, you should never forget that the user can restart the same sequence of events that led to that dialog box, causing a second dialog box to appear.
Propagating environment variables to the parent environment
Under Windows, there is no 'export' directive as in Unix systems. To propagate the value of an environment variable to the rest of the system, use the following registry key:
HKEY_CURRENT_USER \
Environment
You can modify system environment variables by editing the following registry key:
HKEY_LOCAL_MACHINE \
SYSTEM \
CurrentControlSet \
Control \
Session Manager \
Environment
Note that any environment variable that needs to be expanded (for example, when you use %SYSTEM%) must be stored in the registry as a REG_EXPAND_SZ registry value. Any values of type REG_SZ will not be expanded when read from the registry.
The problem with this method, however, is that changes will be effective only after the next logoff, probably not exactly what you want.
To effect these changes without having to log off, broadcast a WM_SETTINGCHANGE message to all windows in the system, so that any applicable applications (such as Program Manager, Task Manager, Control Panel, etc.) can perform an update.
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
(LPARAM) "Environment", SMTO_ABORTIFHUNG,
5000, &dwReturnValue);
In theory, this will work, but there is a problem with Windows 95. Under that system, there is no other way to set those variables than rebooting the system!
Restarting the shell under program control
In many cases it can be necessary to restart the shell. To do this, find the window of the Explorer, send it a quit message, and restart it. The following code snippet will work:
HWND hwndShell = FindWindow("Progman", NULL);
PostMessage(hwndShell, WM_QUIT, 0, 0L);
WinExec("Explorer.exe",SW_SHOW);
Translating client coordinates to screen coordinates
To determine the screen coordinates for the client area of a window, call the ClientToScreen function to translate the client coordinates returned by GetClientRect into screen coordinates. The following code demonstrates how to use the two functions together:
RECT rMyRect;
GetClientRect(hwnd, (LPRECT)&rMyRect);
ClientToScreen(hwnd, (LPPOINT)&rMyRect.left);
ClientToScreen(hwnd, (LPPOINT)&rMyRect.right);
Passing an argument to a dialog box procedure
You can pass a void * to a dialog box procedure by calling:
result = DialogBoxParam(hInst, // Instance of the application.
MAKEINTRESOURCE(id), // The resource ID or dialog box name.
GetActiveWindow(), // The parent window.
Dlgfn, // The dialog box procedure.
(DWORD) "Hello"); // The arguments.
In your dialog box procedure (here DlgFn), you will find those arguments in the lParam parameter of the WM_INITDIALOG message.
Calling printf from a windows application
Windows applications do not have a console, i.e., the 'DOS' window. To access the console from a Windows application, create one, initialize stdout, and use it as you would normally use it from a native console application.
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
int main(void)
Enabling or disabling a button or control in a dialog box.
You should first get the window handle of the control using
hwndControl = GetDlgItem(hwndDlg,IDBUTTON);
Using that window handle, call EnableWindow.
|