/*
PROGRAM: QURYDEMO
========
PURPOSE:
========
demonstrates a simple MDI application that allows a user to
simultaneously connect to multiple hetrogeneous databases
and perform SQL queries to get results.
FUNCTIONS:
==========
WinMain() - main routine
MainWndProc() - processes Main Application Window messages
MDIChildProc() - processes MDI child window messages
ToolbarProc() - processes tool bar messages
StatusbarProc() - processes Status bar messages
ConnectDlgProc() - processes Connection Dialog box messages
DisconnectDlgProc() - processes Disconnect Dialog box messages
AboutDlgProc() - processes messages for About dialog box
MDIChildDlgProc() - processes messages for dummy child dialog box
in MDI child window
DrawBitmap() - draws bitmaps for toolbuttons
COMMENTS:
=========
Created by Microsoft Corporation.
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#ifdef WIN32
#include <windowsx.h>
#else
#include "w16macro.h"
#endif
#include "qurydemo.h"
CONSTSTR(szKeyWord, "query demo, features");
/*
FUNCTION: WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
COMMENTS: Application Entry Routine.
Register Classes. Create Main Window and MDI Child Window.
Process Main Message Loop.
*/
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg; //msg structure
WNDCLASS wc; //class structure
HICON hMainIcon; //App Icon
HICON hMDIChildIcon; //MDI Child Icon
HWND hWndMDIChild; //temp MDI Child Window Handle
char szBuffer[MAXBUFLEN+1]; //temp string buffer to check class name
BOOL bDialogMessage = FALSE; //temp boolean to check dilogbox msgs
HACCEL hAccel; //accelerator table handle
hAppInstance = hInstance;
// check if application is already running, if
// so make it active and bring it in focus
if (hWndFrame = FindWindow(ODBCFRAMECLASS, NULL)) {
hWndFrame = GetLastActivePopup(hWndFrame);
if (IsIconic(hWndFrame))
OpenIcon(hWndFrame);
else
BringWindowToTop(hWndFrame);
ACTIVATEWINDOW(hWndFrame);
return (FALSE);
}
// initialize ODBC Driver Manager Interface
if (!InitSQLEnvironment()) {
MessageBox(hWndFrame, INITERROR, EXECERROR, MB_OK|MB_ICONHAND);
return (FALSE);
}
// register window classes for the application - Main Window Class
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hAppInstance;
wc.hIcon = hMainIcon = LoadIcon(hAppInstance, APPICON);
wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1);
wc.lpszMenuName = QURYDEMOMENU;
wc.lpszClassName = ODBCFRAMECLASS;
if (!RegisterClass(&wc)) {
MessageBox(hWndFrame, CLASSERROR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL);
return (FALSE);
}
// register Toolbar Class
wc.hIcon = (HICON)NULL;
wc.lpszMenuName = NULL;
wc.lpfnWndProc = ToolbarProc;
wc.lpszClassName = ODBCTOOLCLASS;
if (!RegisterClass(&wc)) {
MessageBox(hWndFrame, CLASSERROR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL);
return (FALSE);
}
// register Statusbar Class
wc.lpfnWndProc = StatusbarProc;
wc.lpszClassName = ODBCSTATUSCLASS;
if (!RegisterClass(&wc)) {
MessageBox(hWndFrame, CLASSERROR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL);
return (FALSE);
}
// register MDI Child Window Class
wc.hIcon = hMDIChildIcon = LoadIcon(hAppInstance, QUERYWINDOWICON);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.cbWndExtra = CBWNDEXTRA;
wc.lpszClassName = ODBCMDICLASS;
wc.lpfnWndProc = MDIChildProc;
if (!RegisterClass(&wc)) {
MessageBox(hWndFrame, CLASSERROR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL);
return (FALSE);
}
// create Main window and the MDI Client window
if (!(hWndFrame = CreateWindow(ODBCFRAMECLASS, APPTITLE, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
(HWND)NULL, (HMENU)NULL, hAppInstance, NULL))) {
MessageBox(hWndFrame, CREATEMAINERR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL);
return (FALSE);
}
ShowWindow(hWndFrame, nCmdShow);
UpdateWindow(hWndFrame);
// load accelerators
hAccel = LoadAccelerators(hAppInstance, APPACCELERATOR);
// acquire and dispatch messages until a WM_QUIT message is received
while (GetMessage(&msg, (HWND)NULL, 0, 0)) {
// check for App accelerators
if (TranslateAccelerator(hWndFrame, hAccel, &msg))
continue;
// check for MDI accelerators
if (TranslateMDISysAccel(hWndMDIClient, &msg))
continue;
// each MDI Child has a modeless dialog in its client area
// to provide tab controls. Check for Modeless Dialog msgs.
for (hWndMDIChild = GetWindow(hWndMDIClient, GW_CHILD); hWndMDIChild; hWndMDIChild = GetWindow(hWndMDIChild, GW_HWNDNEXT)) {
GetClassName(hWndMDIChild, szBuffer, MAXBUFLEN);
if (strcmp(szBuffer, ODBCMDICLASS))
continue;
if (IsDialogMessage((HWND)GetWindowLong(hWndMDIChild, GWLAPP_HDLG), &msg)) {
bDialogMessage = TRUE;
break;
}
}
if (bDialogMessage) {
bDialogMessage = FALSE;
continue;
}
// if the message does not need special processing, dispatch it
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// free memory used by ODBC Driver Manager interface
FreeSQLEnvironment();
// free Icon resources
if (hMainIcon)
DestroyIcon(hMainIcon);
if (hMDIChildIcon)
DestroyIcon(hMDIChildIcon);
return (msg.wParam);
}
/*
FUNCTION: MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
COMMENTS: Windows Callback procedure to handle Window messages.
Menu Commands and System Command messages are handled by
this main window.
*/
long CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
static int iToolY; //remember Toolbar height for resize
static int iStatusY; //remember Statusbar height for resize
case WM_CREATE:
{
CLIENTCREATESTRUCT ccs; //MDIclient window structure
HDC hDC; //Device Context handle
SIZE sizeBar; //Size of a text bar
RECT rectCombo; //Size of combo box
// Create child windows
//1. combobox to display connections - DSN, SQLHDBC
//2. combobox to display SQLHSTMT on current SQLHDBC
//3. Toolbar to put toolbuttons
//4. Statusbat to display current action, date and time
//5. MDI Client Window to process MDI children
hWndCrsrList = CreateWindow(COMBOBOXCLASS, NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
WS_VSCROLL | CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL,
5, 2, 180, 150, hWnd,
(HMENU)IDW_CRSRLIST, hAppInstance, NULL);
hWndStmtList = CreateWindow(COMBOBOXCLASS, NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
WS_VSCROLL | CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL,
190, 2, 150, 150, hWnd,
(HMENU)IDW_STMTLIST, hAppInstance, NULL);
hWndToolbar = CreateWindow(ODBCTOOLCLASS, NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
0, 0, 0, 0, hWnd, (HMENU)IDW_TOOLBAR, hAppInstance, NULL);
hWndStatusbar = CreateWindow(ODBCSTATUSCLASS, NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
0, 0, 0, 0, hWnd, (HMENU)IDW_STATUSBAR, hAppInstance, NULL);
ccs.hWindowMenu = GetSubMenu(GetMenu(hWnd), WINDOWMENUPLACE);
ccs.idFirstChild = IDM_MDICHILD;
hWndMDIClient = CreateWindow(MDICLIENTCLASS, NULL,
WS_CHILD | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
0, 0, 0, 0, hWnd,
(HMENU)IDW_MDICLIENT, hAppInstance, (LPSTR)&ccs);
// check to see if any of the above window creation failed
if (!hWndCrsrList || !hWndStmtList || !hWndToolbar || !hWndStatusbar || !hWndMDIClient) {
MessageBox(hWnd, CREATEMAINERR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL);
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
}
// calculate proper text height for tool and status bars
GetWindowRect(hWndStmtList, &rectCombo);
iToolY = rectCombo.bottom - rectCombo.top + TOOLBARMARGINY;
if (hDC = GetDC(hWndStatusbar)) {
GetTextExtentPoint(hDC, ALPHABETS, strlen(ALPHABETS), &sizeBar);
ReleaseDC(hWndStatusbar, hDC);
iStatusY = sizeBar.cy + STATUSBARMARGINY;
}
else {
iStatusY = 0;
DestroyWindow(hWndStatusbar);
}
break;
}
case WM_GETMINMAXINFO:
// limit minimum size of the main window
((MINMAXINFO FAR*)lParam)->ptMinTrackSize.x =
max(MINWIDTH, rectStatusText.right-rectStatusText.left+iTimex+iDatex+14);
((MINMAXINFO FAR*)lParam)->ptMinTrackSize.y = MINHEIGHT;
break;
case WM_SIZE: // resize children
{
WORD wWidth = LOWORD(lParam); //width of rectangle
WORD wHeight = HIWORD(lParam); //height of rectangle
MoveWindow(hWndToolbar, 0, 0, wWidth, iToolY, TRUE);
MoveWindow(hWndStatusbar, 0, wHeight-iStatusY, wWidth, iStatusY, TRUE);
InvalidateRect(hWndStatusbar, NULL, TRUE);
MoveWindow(hWndMDIClient, 0, iToolY, wWidth, wHeight-iStatusY-iToolY, TRUE);
break;
}
case WM_SYSCOLORCHANGE: // inform 3D controls of color change
// Ctl3dColorChange();
break;
case WM_SYSCOMMAND: // close comboboxes if dropped down
SendMessage(hWndCrsrList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
SendMessage(hWndStmtList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
return (DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam));
case WM_INITMENUPOPUP: // initialize popup menus
{
int iMenuId; //Menu ID being processed
int nItems; //# of menu items
int nPos; //Menu Position
//ignore the msg if it is for a system menu
if (HIWORD(lParam))
break;
// Go through the menu items for current popup menu
// and enable/disable menu item, if required
nItems = GetMenuItemCount((HMENU)wParam);
for (nPos = 0; nPos < nItems; nPos++)
switch (iMenuId = GetMenuItemID((HMENU)wParam, nPos)) {
case IDM_DISCONNECT:
case IDM_NEW:
EnableMenuItem((HMENU)wParam, iMenuId, MF_BYCOMMAND|
((SendMessage(hWndCrsrList, CB_GETCOUNT, 0, 0) > 0)
? MF_ENABLED
: MF_GRAYED));
break;
case IDM_QUERY:
case IDM_TILE:
case IDM_CASCADE:
case IDM_ICONS:
case IDM_CLOSEALL:
EnableMenuItem((HMENU)wParam, iMenuId, MF_BYCOMMAND|
(GetWindow(hWndMDIClient, GW_CHILD)
? MF_ENABLED
: MF_GRAYED));
break;
default:
break;
}
break;
}
case WM_MENUSELECT: // update status bar to reflect menu selection
{
int iMenuFlag; //Check menu type
HMENU hMenu; //Menu Handle
char szMenuName[MAXBUFLEN+1];//Menu Name
// store Menuitem ID as a state value for text display
wStatusText = GET_WM_MENUSELECT_CMD(wParam, lParam);
// process popup menus ie non menuitem selections
iMenuFlag = GET_WM_MENUSELECT_FLAGS(wParam, lParam);
// if the selected menu is a system popup menu
if (wStatusText && (iMenuFlag & MF_SYSMENU) && (iMenuFlag & MF_POPUP))
wStatusText = IDM_POPUPAPPSYS;
// else if the selected menu is a popup menu check menu names
// OR check if it is a control popup menu of maximized MDI Child window
else if (wStatusText && (iMenuFlag & MF_POPUP)) {
hMenu = (HMENU)wStatusText;
GetMenuString(hMenu, 0, szMenuName, MAXBUFLEN, MF_BYPOSITION);
if (!strcmp(szMenuName, MENUITEMCONNECT))
wStatusText = IDM_POPUPLOGIN;
else if (!strcmp(szMenuName, MENUITEMQUERY))
wStatusText = IDM_POPUPQUERY;
else if (!strcmp(szMenuName, MENUITEMTILE))
wStatusText = IDM_POPUPWINDOW;
else if (!strcmp(szMenuName, MENUITEMAPPHELP))
wStatusText = IDM_POPUPHELP;
else if (GetMenuString(hMenu, SC_NEXTWINDOW, szMenuName, MAXBUFLEN, MF_BYCOMMAND)>0)
wStatusText = IDM_POPUPMDISYS;
else
wStatusText = 0;
}
// invalidate status bar for repaint
InvalidateRect(hWndStatusbar, &rectStatusText, TRUE);
break;
}
case WM_COMMAND: // process menu commands
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDM_CONNECT: // bring up connect dialog & do connect processing
DialogBox(hAppInstance, CONNECTDIALOG, hWnd,ConnectDlgProc);
break;
case IDM_DRIVERCONNECT: // let the driver do the dialogs
DriverConnectDatabase(hWnd);
break;
case IDM_DISCONNECT: // bringup disconnect dlg and do disconnects
DialogBox(hAppInstance, DISCONNECTDIALOG, hWnd,DisconnectDlgProc);
break;
case IDM_QUERY: // process execute query request
ExecuteQuery();
break;
case IDM_EXIT: // process exit request
SendMessage(hWndFrame, WM_CLOSE, 0, 0);
break;
case IDM_NEW: // create a new query window on current connect
NewQueryWindow();
break;
case IDM_TILE: // let MDI Client tile the MDI children
SendMessage(hWndMDIClient, WM_MDITILE, 0, 0);
break;
case IDM_CASCADE: // let MDI Client cascade MDI children
SendMessage(hWndMDIClient, WM_MDICASCADE, 0, 0);
break;
case IDM_ICONS: // let MDI Client arrange iconic MDI children
SendMessage(hWndMDIClient, WM_MDIICONARRANGE, 0, 0);
break;
case IDM_CLOSEALL: // Close all open windows and free hstmts
{
HWND hWndTemp; //temp window handle
// hide MDI Client Windows to avoid repaints
ShowWindow(hWndMDIClient,SW_HIDE);
while (hWndTemp = GetWindow(hWndMDIClient, GW_CHILD))
SendMessage(hWndMDIClient, WM_MDIDESTROY, (WPARAM)hWndTemp, 0);
ShowWindow(hWndMDIClient, SW_SHOW);
break;
}
case IDM_APPHELP: // bring up Samples Help file
WinHelp(hWnd, SAMPLESHELPFILE, HELP_KEY,(DWORD)(LPTSTR)szKeyWord);
break;
case IDM_ABOUT: // bringup About dialog
DialogBox(hAppInstance, ABOUTDIALOG, hWnd, AboutDlgProc);
break;
case IDW_CRSRLIST: // change current cursor ?
if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE)
ChangeCurrentCursor(GET_WM_COMMAND_HWND(wParam, lParam));
else if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_KILLFOCUS)
PostMessage(GET_WM_COMMAND_HWND(wParam, lParam), CB_SHOWDROPDOWN,
(WPARAM)FALSE, 0);
else
DefFrameProc(hWnd, hWndMDIClient, WM_COMMAND, wParam, lParam);
break;
case IDW_STMTLIST: // change current hstmt?
if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE)
ChangeCurrentQuery(GET_WM_COMMAND_HWND(wParam, lParam));
else if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_KILLFOCUS)
PostMessage(GET_WM_COMMAND_HWND(wParam, lParam), CB_SHOWDROPDOWN,
(WPARAM)FALSE, 0);
else
DefFrameProc(hWnd, hWndMDIClient, WM_COMMAND, wParam, lParam);
break;
default:
DefFrameProc(hWnd, hWndMDIClient, WM_COMMAND, wParam, lParam);
break;
}
break;
case WM_CLOSE: //close all MDI windows, hdbcs & hstmts, else fail
return (CloseDatabases()
? DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam)
: FALSE);
case WM_DESTROY:
// Close Help File if open
WinHelp(hWnd, SAMPLESHELPFILE, HELP_QUIT, 0);
PostQuitMessage(0);
break;
default:
return (DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam));
}
return (0);
}
/*
FUNCTION: MDIChildProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
COMMENTS: Window Procedure for MDI Child windows
*/
long CALLBACK MDIChildProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
HWND hWndTemp; //temporary window handle
DLGPROC lpDlgProc; //procedure address for modeless dialog
case WM_CREATE:
// create child windows
// 1. Modeless Dialog box in the background to process tabs
// 2. Static Text to display prompt
// 3. Edit Control to type SQL text
// 4. List Box to display results
// store dialog handle for future reference
// set focus to edit control
// if create failed due to low system resources
if (!hWnd)
break;
hWndActiveChild = hWnd;
hWndTemp = CreateDialog(hAppInstance, MDICHILDDIALOG, hWndActiveChild, MDIChildDlgProc);
// check to see if the dialog was created?, if not destroy this window
if (!hWndTemp) {
return (-1);
}
SetWindowLong(hWnd, GWLAPP_HDLG, (LONG)hWndTemp);
SetFocus(GetDlgItem(hWndTemp, IDTEXT_SQL));
break;
case WM_SIZE: {
WORD wWidth; //New Width of MDI Child
WORD wHeight; //New Height of MDI Child
HDC hDC; //Device Context
char szBuffer[MAXBUFLEN+1]; //Static Control Text
int nStrLen; //Buffer Length
SIZE size; //Screen size for text display
// call default procedure first, to let MDI position the child & then move its children
DefMDIChildProc(hWnd, message, wParam, lParam);
// move child windows with proper screen size for text display
wWidth = LOWORD(lParam);
wHeight = HIWORD(lParam);
hWndTemp = (HWND)GetWindowLong(hWnd, GWLAPP_HDLG);
nStrLen = GetWindowText(GetDlgItem(hWndTemp, IDTEXT_PRMPT), szBuffer, MAXBUFLEN);
hDC = GetDC(hWnd);
GetTextExtentPoint(hDC, szBuffer, nStrLen, &size);
ReleaseDC(hWnd, hDC);
MoveWindow(hWndTemp, 0, 0, wWidth, wHeight, TRUE);
MoveWindow(GetDlgItem(hWndTemp, IDTEXT_PRMPT), 0, 0, size.cx+2, size.cy+2, TRUE);
MoveWindow(GetDlgItem(hWndTemp, IDTEXT_SQL), size.cx+3, 0, wWidth - (size.cx+2), size.cy+2, TRUE);
MoveWindow(GetDlgItem(hWndTemp, IDLIST_RSLT), 0, size.cy+3, wWidth, wHeight - (size.cy+2), TRUE);
break;
}
case WM_MENUSELECT: // update status bar to reflect menu selection
{
int iMenuFlag; //Check menu type
// store the Menu Item Id as a state value for text display
wStatusText = GET_WM_MENUSELECT_CMD(wParam, lParam);
// if none of the menuitems was selected, check if
// the control popup menu is selected.
iMenuFlag = GET_WM_MENUSELECT_FLAGS(wParam, lParam);
// if the selected menu is a system popup menu
if (wStatusText && (iMenuFlag & MF_SYSMENU) && (iMenuFlag & MF_POPUP))
wStatusText = IDM_POPUPMDISYS;
// invalidate status bar for repaint
InvalidateRect(hWndStatusbar, &rectStatusText, TRUE);
break;
}
case WM_MDIACTIVATE:
// check if the display of comboboxes require a change
if (GET_WM_MDIACTIVATE_FACTIVATE(hWnd, wParam, lParam) &&
(hWndActiveChild) && (hWndActiveChild != hWnd)) {
hWndActiveChild = hWnd;
DisplayNewCrsrAndStmt();
}
break;
case WM_MOUSEACTIVATE:
// current window has changed, update comboboxes.
hWndActiveChild = hWnd;
DisplayNewCrsrAndStmt();
break;
case WM_SETFOCUS:
// pass on the focus to the edit box for user to type in SQL
SetFocus(GetDlgItem((HWND)GetWindowLong(hWnd, GWLAPP_HDLG), IDTEXT_SQL));
break;
case WM_DESTROY:
// check if the window was being destroyed while creation failed
if (!hWnd)
break;
// close the window and free instance thunk for modeless dialog
CloseQueryWindow(hWnd);
lpDlgProc = (DLGPROC)GetWindowLong((HWND)GetWindowLong(hWnd, GWLAPP_HDLG), DWL_DLGPROC);
DestroyWindow((HWND)GetWindowLong(hWnd, GWLAPP_HDLG));
FreeProcInstance(lpDlgProc);
if (hWnd == hWndActiveChild)
hWndActiveChild = (HWND)NULL;
break;
default:
return (DefMDIChildProc(hWnd, message, wParam, lParam));
}
return (0);
}
/*
FUNCTION: ToolbarProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
COMMENTS: callback window procedure for toolbar window.
Handle pain and mouse messages to paint the toolbar and
provide default button behaviour for toolbar buttons.
*/
long CALLBACK ToolbarProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
static HBITMAP hbmpNewQuery; //btn1 bitmap handle
static HBITMAP hbmpRunQuery; //btn2 bitmap handle
static RECT stNewQuery; //btn1 rectangle
static RECT stRunQuery; //btn2 rectangle
POINT stMousePosition; //current mouse pos
BOOL bButtonPosition; //mouse pos flag
static BOOL bNewQueryBtnDown = FALSE; //was btn1 down before?
static BOOL bRunQueryBtnDown = FALSE; //was btn2 down before?
static int nLastButtonDown = 0; //Which btn was down before?
case WM_CREATE:
// load bitmaps for buttons
// initialize static rectangles for button positions on toolbar
// initialize state variable for status text display
hbmpNewQuery = LoadBitmap(hAppInstance, BMP_NEWQUERY);
hbmpRunQuery = LoadBitmap(hAppInstance, BMP_RUNQUERY);
stNewQuery.left = BTTNX;
stNewQuery.right = BTTNX+BTTNWIDTH+1;
stNewQuery.top = BTTNY;
stNewQuery.bottom = BTTNY+BTTNHEIGHT+1;
stRunQuery.left = BTTNX+BTTNWIDTH+BTTNMARGIN;
stRunQuery.right = BTTNX+BTTNWIDTH+BTTNMARGIN+BTTNWIDTH+1;
stRunQuery.top = BTTNY;
stRunQuery.bottom = BTTNY+BTTNHEIGHT+1;
wStatusText = 0;
break;
case WM_DESTROY:
// delete bitmap handles
if (hbmpNewQuery)
DeleteObject(hbmpNewQuery);
if (hbmpRunQuery)
DeleteObject(hbmpRunQuery);
break;
case WM_LBUTTONDOWN:
// Check if the mouse key lies on any one of the buttons
// if so, set state variable to reflect that button and
// invalidate proper regions on tool & status bars for update.
// set capture on mouse movements till the mouse key is
// released.
stMousePosition.x = LOWORD(lParam);
stMousePosition.y = HIWORD(lParam);
if (PtInRect(&stNewQuery, stMousePosition)) {
bNewQueryBtnDown = TRUE;
wStatusText = nLastButtonDown = IDM_NEW;
SetCapture(hWnd);
InvalidateRect(hWnd, &stNewQuery, TRUE);
InvalidateRect(hWndStatusbar, &rectStatusText, TRUE);
}
else if (PtInRect(&stRunQuery, stMousePosition)) {
bRunQueryBtnDown = TRUE;
wStatusText = nLastButtonDown = IDM_QUERY;
SetCapture(hWnd);
InvalidateRect(hWnd, &stRunQuery, TRUE);
InvalidateRect(hWndStatusbar, &rectStatusText, TRUE);
}
break;
case WM_LBUTTONUP:
// check if the mouse movements from key down movements
// were captured, if so process the key release state.
// if the key was released in the same button where it
// was pressed, it is equivalent to a button click.
if (hWnd != GetCapture())
break;
stMousePosition.x = LOWORD(lParam);
stMousePosition.y = HIWORD(lParam);
if (bNewQueryBtnDown && PtInRect(&stNewQuery, stMousePosition)) {
bNewQueryBtnDown = FALSE;
nLastButtonDown = 0;
InvalidateRect(hWnd, &stNewQuery, TRUE);
PostMessage(hWndFrame, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_NEW, 0, 0));
SendMessage(hWndCrsrList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
SendMessage(hWndStmtList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
}
else if (bRunQueryBtnDown && PtInRect(&stRunQuery, stMousePosition)) {
bRunQueryBtnDown = FALSE;
nLastButtonDown = 0;
InvalidateRect(hWnd, &stRunQuery, TRUE);
PostMessage(hWndFrame, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_QUERY, 0, 0));
SendMessage(hWndCrsrList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
SendMessage(hWndStmtList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
}
ReleaseCapture();
wStatusText = 0;
InvalidateRect(hWndStatusbar, &rectStatusText, TRUE);
break;
case WM_MOUSEMOVE:
// process mouse movement only if the mouse key was pressed
// down and its movements were being captured. If the mouse
// moves outside of the currently depressed button, it needs
// to be drawn again with normal state.
if (hWnd != GetCapture())
break;
stMousePosition.x = LOWORD(lParam);
stMousePosition.y = HIWORD(lParam);
if (nLastButtonDown == IDM_NEW) {
bButtonPosition = PtInRect(&stNewQuery, stMousePosition);
if (bNewQueryBtnDown != bButtonPosition) {
bNewQueryBtnDown = bButtonPosition;
InvalidateRect(hWnd, &stNewQuery, TRUE);
}
}
else if (nLastButtonDown == IDM_QUERY) {
bButtonPosition = PtInRect(&stRunQuery, stMousePosition);
if (bRunQueryBtnDown != bButtonPosition) {
bRunQueryBtnDown = bButtonPosition;
InvalidateRect(hWnd, &stRunQuery, TRUE);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps; //paint structure
RECT rect; //rectangle for tool bar
HDC hDC; //device context handle
int iWidth; //tool bar width
int iHeight; //tool bar height
HPEN hLtGrayPen; //buttonface color pen
HPEN hGrayPen; //buttonshadow color pen
int btnx; //button x coordinate position
if (!(hDC = BeginPaint(hWnd, &ps)))
break;
GetClientRect(hWnd, &rect);
iWidth = rect.right;
iHeight = rect.bottom;
hLtGrayPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNFACE));
hGrayPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));
// draw background and border
SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
SelectObject(hDC, hLtGrayPen);
Rectangle(hDC, 0, 0, iWidth, iHeight);
SelectObject(hDC, GetStockObject(BLACK_PEN));
MoveToEx(hDC, 0, iHeight-1, NULL);
LineTo(hDC, iWidth, iHeight-1);
SelectObject(hDC, GetStockObject(WHITE_PEN));
MoveToEx(hDC, 0, 0, NULL);
LineTo(hDC, iWidth, 0);
// draw tool bar buttons (new query, run query)
// check state variables to draw proper button state
btnx = BTTNX;
SelectObject(hDC, GetStockObject(BLACK_PEN));
DRAWBTTNRECT(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
DrawBitmap(hDC, (bNewQueryBtnDown?btnx+3:btnx+2), (bNewQueryBtnDown?BTTNY+3:BTTNY+2), hbmpNewQuery);
SelectObject(hDC, (bNewQueryBtnDown ? hGrayPen : GetStockObject(WHITE_PEN)));
DRAWBTTNLIFT1(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
SelectObject(hDC, (bNewQueryBtnDown ? hLtGrayPen : hGrayPen));
DRAWBTTNLIFT2(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
btnx += BTTNWIDTH+BTTNMARGIN;
SelectObject(hDC, GetStockObject(BLACK_PEN));
DRAWBTTNRECT(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
DrawBitmap(hDC, (bRunQueryBtnDown?btnx+3:btnx+2), (bRunQueryBtnDown?BTTNY+3:BTTNY+2), hbmpRunQuery);
SelectObject(hDC, (bRunQueryBtnDown ? hGrayPen : GetStockObject(WHITE_PEN)));
DRAWBTTNLIFT1(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
SelectObject(hDC, (bRunQueryBtnDown ? hLtGrayPen : hGrayPen));
DRAWBTTNLIFT2(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
SelectObject(hDC, GetStockObject(WHITE_PEN));
EndPaint(hWnd, &ps);
// delete create objects
if (hLtGrayPen)
DeleteObject(hLtGrayPen);
if (hGrayPen)
DeleteObject(hGrayPen);
break;
}
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
/*
FUNCTION: StatusbarProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
COMMENTS: callback window procedure for status bar.
process paint messages and timer messages to update current
state, date and time
*/
long CALLBACK StatusbarProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
static RECT DateTimeRect; // remember for frequent updates
case WM_CREATE:
{
HDC hDC; // device context
SIZE sizeText; // size of status text box
SIZE sizeTime; // size of time display box
SIZE sizeDate; // size of date display box
// start a timer for periodic updates to date and time display
// find out width of status text, date and time display boxes
SetTimer(hWnd, (UINT)IDT_STATUSTIMER, (UINT)TIMERDELAY, NULL);
iTimex = iDatex = 0;
rectStatusText.left = 2;
rectStatusText.top = 3;
if (hDC = GetDC(hWnd)) {
GetTextExtentPoint(hDC, STATUSNEW, strlen(STATUSNEW), &sizeText);
GetTextExtentPoint(hDC, TIMETEXT, strlen(TIMETEXT), &sizeTime);
GetTextExtentPoint(hDC, DATETEXT, strlen(DATETEXT), &sizeDate);
ReleaseDC(hWnd, hDC);
rectStatusText.right = sizeText.cx + rectStatusText.left;
iTimex = sizeTime.cx;
iDatex = sizeDate.cx;
}
break;
}
case WM_TIMER:
// invalidate only the date&time area for update
InvalidateRect(hWnd, &DateTimeRect, TRUE);
break;
case WM_PAINT:
{
HDC hDC; //device context
PAINTSTRUCT ps; //paint structure
RECT rect; //status bar rect
int iWidth; //status bar width
int iHeight; //status bar height
HPEN hLtGrayPen; //btnface color pen
HPEN hGrayPen; //btnshadow color pen
char szText[MAXBUFLEN]; //text buffer for display
time_t tCurrentTime; //current date&time
struct tm stTime; //date&time structure
if (!(hDC = BeginPaint(hWnd, &ps)))
break;
GetClientRect(hWnd, &rect);
iWidth = rect.right;
iHeight = rect.bottom;
rectStatusText.bottom = iHeight-2;
hLtGrayPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNFACE));
hGrayPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));
// paint background and border
SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
SelectObject(hDC, hLtGrayPen);
Rectangle(hDC, 0, 0, iWidth, iHeight);
SelectObject(hDC, GetStockObject(BLACK_PEN));
MoveToEx(hDC, 0, 0, NULL);
LineTo(hDC, iWidth, 0);
SelectObject(hDC, GetStockObject(WHITE_PEN));
MoveToEx(hDC, 0, 1, NULL);
LineTo(hDC, iWidth, 1);
// draw text boxes for status, time and date display
SelectObject(hDC, hGrayPen);
MoveToEx(hDC, rectStatusText.left, rectStatusText.bottom, NULL);
LineTo(hDC, rectStatusText.left, rectStatusText.top);
LineTo(hDC, rectStatusText.right, rectStatusText.top);
SelectObject(hDC, GetStockObject(WHITE_PEN));
LineTo(hDC, rectStatusText.right, rectStatusText.bottom);
LineTo(hDC, rectStatusText.left, rectStatusText.bottom);
SelectObject(hDC, hGrayPen);
MoveToEx(hDC, iWidth-2, 3, NULL);
LineTo(hDC, iWidth-iDatex-2, 3);
LineTo(hDC, iWidth-iDatex-2, iHeight-2);
SelectObject(hDC, GetStockObject(WHITE_PEN));
LineTo(hDC, iWidth-2, iHeight-2);
LineTo(hDC, iWidth-2, 3);
SelectObject(hDC, hGrayPen);
MoveToEx(hDC, iWidth-iDatex-6, 3, NULL);
LineTo(hDC, iWidth-iTimex-iDatex-6, 3);
LineTo(hDC, iWidth-iTimex-iDatex-6, iHeight-2);
SelectObject(hDC, GetStockObject(WHITE_PEN));
LineTo(hDC, iWidth-iDatex-6, iHeight-2);
LineTo(hDC, iWidth-iDatex-6, 3);
// draw status text in the display box based on current
// value of wStatusText global flag
SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT));
switch (wStatusText) {
case IDM_POPUPAPPSYS:
strcpy(szText, STATUSPOPUPAPPSYS);
break;
case IDM_POPUPMDISYS:
strcpy(szText, STATUSPOPUPMDISYS);
break;
case SC_RESTORE:
strcpy(szText, STATUSRESTORE);
break;
case SC_MOVE:
strcpy(szText, STATUSMOVE);
break;
case SC_SIZE:
strcpy(szText, STATUSSIZE);
break;
case SC_MINIMIZE:
strcpy(szText, STATUSMINIMIZE);
break;
case SC_MAXIMIZE:
strcpy(szText, STATUSMAXIMIZE);
break;
case SC_CLOSE:
strcpy(szText, STATUSCLOSE);
break;
case SC_NEXTWINDOW:
strcpy(szText, STATUSNEXTWINDOW);
break;
case SC_PREVWINDOW:
strcpy(szText, STATUSPREVWINDOW);
break;
case SC_TASKLIST:
strcpy(szText, STATUSTASKLIST);
break;
case IDM_POPUPLOGIN:
strcpy(szText, STATUSPOPUPLOGIN);
break;
case IDM_CONNECT:
strcpy(szText, STATUSCONNECT);
break;
case IDM_DRIVERCONNECT:
strcpy(szText, STATUSDRIVERCONNECT);
break;
case IDM_DISCONNECT:
strcpy(szText, STATUSDISCONNECT);
break;
case IDM_EXIT:
strcpy(szText, STATUSEXIT);
break;
case IDM_POPUPQUERY:
strcpy(szText, STATUSPOPUPQUERY);
break;
case IDM_QUERY:
strcpy(szText, STATUSQUERY);
break;
case IDM_NEW:
strcpy(szText, STATUSNEW);
break;
case IDM_POPUPWINDOW:
strcpy(szText, STATUSPOPUPWINDOW);
break;
case IDM_TILE:
strcpy(szText, STATUSTILE);
break;
case IDM_CASCADE:
strcpy(szText, STATUSCASCADE);
break;
case IDM_ICONS:
strcpy(szText, STATUSICONS);
break;
case IDM_CLOSEALL:
strcpy(szText, STATUSCLOSEALL);
break;
case IDM_POPUPHELP:
strcpy(szText, STATUSPOPUPHELP);
break;
case IDM_APPHELP:
strcpy(szText, STATUSAPPHELP);
break;
case IDM_ABOUT:
strcpy(szText, STATUSABOUT);
break;
default:
if (wStatusText >= IDM_MDICHILD)
sprintf(szText, STATUSMDICHILD, wStatusText-IDM_MDICHILD+1);
else
strcpy(szText, STATUSDEFAULT);
break;
}
DrawText(hDC, szText, strlen(szText), &rectStatusText, DT_LEFT);
// get current date and time and display time in time box
time(&tCurrentTime);
stTime = *localtime(&tCurrentTime);
strftime(szText, MAXBUFLEN, TIMEFORMAT, &stTime);
rect.top = rectStatusText.top;
rect.bottom = rectStatusText.bottom;
rect.left = iWidth-iTimex-iDatex-6;
rect.right = iWidth-iDatex-6;
DrawText(hDC, szText, strlen(szText), &rect, DT_LEFT);
// display date in date box
strftime(szText, MAXBUFLEN, DATEFORMAT, &stTime);
rect.left = iWidth-iDatex-2;
rect.right = iWidth-2;
DrawText(hDC, szText, strlen(szText), &rect, DT_LEFT);
// remember the date&time rectangle to minimize painting
DateTimeRect.left = iWidth-iTimex-iDatex-6;
DateTimeRect.right = iWidth-2;
DateTimeRect.top = rect.top;
DateTimeRect.bottom = rect.bottom;
EndPaint(hWnd, &ps);
// delete created objects
if (hLtGrayPen)
DeleteObject(hLtGrayPen);
if (hGrayPen)
DeleteObject(hGrayPen);
break;
}
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
break;
}
return (0);
}
/*
FUNCTION: ConnectDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
COMMENTS: Callback dialog box procedure for connect menu command
displays a list of available data sources, asks for user
name and password to pass default connection parameters
for a data source connection
*/
BOOL CALLBACK ConnectDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
HCURSOR hOldCursor; // Default Cursor Shape
case WM_INITDIALOG:
// display list of available data sources
hOldCursor = SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
DisplayDatabases(GetDlgItem(hWnd, IDCOMBO_DATASOURCE));
SetCursor(hOldCursor);
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK: // make a connection using the supplied values
hOldCursor = SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
// check if a DSN was provided for connection
if (SendDlgItemMessage(hWnd, IDCOMBO_DATASOURCE, WM_GETTEXTLENGTH, 0, 0))
EndDialog(hWnd, ConnectDatabase(hWnd));
else
MessageBox(hWnd, NODSNERR, MOREINFO, MB_OK|MB_ICONHAND);
SetCursor(hOldCursor);
break;
case IDCANCEL:
EndDialog(hWnd, FALSE);
break;
default:
return (FALSE);
break;
}
break;
default:
return (FALSE);
break;
}
return (TRUE);
}
/*
FUNCTION: DisconnectDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
COMMENTS: Callback dialog box procedure for disconnect dialog.
provides a list of available SQLHDBCs and a list of SQLHSTMTs
for currently selected SQLHDBC. Allows closure of all SQLHDBCs
and SQLHSTMTs one by one or in groups.
*/
BOOL CALLBACK DisconnectDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
static HWND hListhdbc; //listbox that displays hdbc(s)
static HWND hListstmt; //listbox that displays hstmt(s)
static HWND hPushOk; //pushbutton to free hdbc
static HWND hPushClose; //pushbutton to free hstmt
static HWND hPushCancel; //pushbutton to close dialog
case WM_INITDIALOG:
// store handles for future reference
hListhdbc = GetDlgItem(hWnd, IDLIST_HDBC);
hListstmt = GetDlgItem(hWnd, IDLIST_STMT);
hPushOk = GetDlgItem(hWnd, IDDISCONNECT);
hPushCancel = GetDlgItem(hWnd, IDCANCEL);
hPushClose = GetDlgItem(hWnd, IDCLOSE_ACTVTY);
// display connected database handles and statements
DisplayConnections(hListhdbc);
DisplayQueries(hListstmt, hListhdbc, 0);
// enable or disable pushbuttons & listboxes to match available hdbc & hstmt
if (SendMessage(hListhdbc, LB_GETCOUNT, 0, 0)>0) {
EnableWindow(hPushOk, TRUE);
if (SendMessage(hListstmt, LB_GETCOUNT, 0, 0)>0) {
EnableWindow(hPushClose, TRUE);
SetFocus(hPushClose);
SendMessage(hPushClose, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
}
else {
EnableWindow(hListstmt, FALSE);
EnableWindow(hPushClose, FALSE);
SetFocus(hPushOk);
SendMessage(hPushOk, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
}
}
else {
EnableWindow(hListhdbc, FALSE);
EnableWindow(hListstmt, FALSE);
EnableWindow(hPushOk, FALSE);
SetFocus(hPushCancel);
SendMessage(hPushCancel, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
}
// return FALSE to prevent default focus.
return (FALSE);
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDDISCONNECT:
// Free current hdbc, display available hdbc(s)
FreeConnect(hListhdbc);
SendMessage(hListstmt, LB_RESETCONTENT, 0, 0);
DisplayConnections(hListhdbc);
// update displayed hstmt(s) for current hdbc
// enable or disable pushbuttons to match available
// hdbc(s) and hstmt(s) for closure
if (SendMessage(hListhdbc, LB_GETCOUNT, 0, 0) > 0) {
SendMessage(hListhdbc, LB_SETCURSEL, 0, 0);
EnableWindow(hListstmt, TRUE);
DisplayQueries(hListstmt, hListhdbc, 0);
if (SendMessage(hListstmt, LB_GETCOUNT, 0, 0)>0) {
EnableWindow(hPushClose, TRUE);
SetFocus(hPushClose);
SendMessage(hPushClose, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
}
else {
EnableWindow(hListstmt, FALSE);
EnableWindow(hPushClose, FALSE);
SetFocus(hPushOk);
SendMessage(hPushOk, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
}
}
else {
EnableWindow(hListhdbc, FALSE);
EnableWindow(hPushOk, FALSE);
EnableWindow(hPushClose, FALSE);
SetFocus(hPushCancel);
SendMessage(hPushCancel, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
}
break;
case IDCANCEL:
// close dialog
EndDialog(hWnd, FALSE);
break;
case IDCLOSE_ACTVTY:
{
int nIndex; // counter to search for selected hstmt(s)
// go through all displayed hstmt(s) and free all highlighted ones
for (nIndex = (int)SendMessage(hListstmt, LB_GETCOUNT, 0, 0)-1;
nIndex >= 0; nIndex--)
if (SendMessage(hListstmt, LB_GETSEL, nIndex, 0))
FreeQuery(hListstmt, hListhdbc, nIndex);
// reset both hdbc(s) and hstmt(s) display
nIndex = (int)SendMessage(hListhdbc, LB_GETCURSEL, 0, 0);
DisplayConnections(hListhdbc);
SendMessage(hListhdbc, LB_SETCURSEL, nIndex, 0);
DisplayQueries(hListstmt, hListhdbc, nIndex);
// enable or disable pushbuttons to match available
// hdbc(s) and hstmt(s) for closure
if (SendMessage(hListstmt, LB_GETCOUNT, 0, 0)>0) {
EnableWindow(hPushClose, TRUE);
SetFocus(hPushClose);
SendMessage(hPushClose, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
}
else {
EnableWindow(hListstmt, FALSE);
EnableWindow(hPushClose, FALSE);
SetFocus(hPushOk);
SendMessage(hPushOk, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
}
break;
}
case IDLIST_HDBC:
// If the current selection in hdbc(s) has changed
// update the list of hstmt(s) to match the new hdbc
if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_SELCHANGE)
DisplayQueries(hListstmt, hListhdbc,
(UINT)SendMessage(GET_WM_COMMAND_HWND(wParam, lParam), LB_GETCURSEL, 0, 0));
// Enable or disable hstmt listbox and close pushbutton accordingly
EnableWindow(hListstmt, (SendMessage(hListstmt, LB_GETCOUNT, 0, 0)>0));
EnableWindow(hPushClose, (SendMessage(hListstmt, LB_GETCOUNT, 0, 0)>0));
break;
default:
return (FALSE);
}
break;
default:
return (FALSE);
}
return (TRUE);
}
/*
FUNCTION: AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
COMMENTS: Callback dialog box procedure for About dialog box
displays the about information and closes upon selection of
ok button
*/
BOOL CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_COMMAND) {
EndDialog(hWnd, TRUE);
return (TRUE);
}
else
return (FALSE);
}
/*
FUNCTION: MDIChildDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
COMMENTS: Callback dialog box procedure for modeless child dialog box
in each MDI Child Window. This dialog box simply processes
the tab messages (by default) to allow switching from edit
control (SQL Text) to list box control (Query results).
*/
BOOL CALLBACK MDIChildDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return (FALSE);
}
/*
FUNCTION: DrawBitmap(HDC hDC, int iLeft, int iTop, HBITMAP hBitmap
COMMENTS: Draws a bitmap on given Device context with given bitmap
handle at given location
*/
VOID FAR PASCAL DrawBitmap(HDC hDC, int iLeft, int iTop, HBITMAP hBitmap)
{
HDC hMemDC; // Device Context in Memory
POINT stPoint; // point structure for conversion from device to logical units
BITMAP stBitmap;
HGDIOBJ hObject;
// create a compatible device context in memory and select the bitmap
// in to it.
if (!(hMemDC = CreateCompatibleDC(hDC))) return;
hObject = SelectObject(hMemDC, hBitmap);
SetMapMode(hMemDC, GetMapMode(hDC));
// Get bitmap size and convert it to logical units from device units.
GetObject(hBitmap, sizeof(BITMAP), &stBitmap);
stPoint.x = stBitmap.bmWidth;
stPoint.y = stBitmap.bmHeight;
DPtoLP(hDC, &stPoint, 1);
// bit block transfer the bitmap from memory device context to given
// device context at specified location
BitBlt(hDC, iLeft, iTop, stPoint.x, stPoint.y, hMemDC, 0, 0, SRCCOPY);
// select original object in the memory device context and destroy it
SelectObject(hMemDC, hObject);
DeleteDC(hMemDC);
}
/********************************************* END OF FILE **************************************************/