#include <windows.h>
#include <commctrl.h>
#include <process.h>
#include <stdio.h>
#include <wsqllib.h>
#include <winlib/winlib.h>
#include "sqlbase.h"
#include "dbinit.h"
#include "dbroutes.h"
#include "dbutil.h"
#include "sqlcmd.h"
void MoveControls(VARS *v, int xPos, int yPos)
{
int i, xStart, yStart;
RECT rect;
SQLFIELD *f;
xStart = -xPos;
yStart = -yPos;
for (i = 0, f = v->fields; i < v->nFields;
i++, f = f->next) {
MoveWindow(v->hwndLabel[i],
f->x * v->xScale + xStart, f->y * v->yScale + yStart + 3,
f->labelWidth * v->xScale, v->cyChar * 1.5,
FALSE);
MoveWindow(v->hwndEdit[i],
f->x * v->xScale + f->labelWidth * v->xScale + 15 + xStart,
f->y * v->yScale + yStart,
f->editWidth * v->xScale, v->cyChar * 1.5,
FALSE);
}
(void) GetClientRect(v->hwndCont, &rect);
InvalidateRect(v->hwndCont, &rect, TRUE);
}
void ResizeChildren(VARS *v)
{
RECT mainRect, statusRect;
GetClientRect(v->hwndMain, &mainRect);
GetWindowRect(v->hwndStatus, &statusRect);
MoveWindow(v->hwndCont,
0, 0, mainRect.right, mainRect.bottom - (statusRect.bottom - statusRect.top),
TRUE);
}
void CreateChildren(VARS *v, HWND hwnd)
{
int i;
HFONT hfnt = GetStockObject(ANSI_VAR_FONT);
SQLFIELD *f;
v->hwndCont = CreateWindowEx(
WS_EX_CLIENTEDGE, "ContWndClass", (LPCTSTR)NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL,
0, 0, 0, 0,
hwnd, NULL, v->hInst, (LPVOID)v);
for (i = 0, f = v->fields; i < v->nFields;
i++, f = f->next) {
v->hwndLabel[i] = CreateWindowEx(
0, "STATIC", (LPCTSTR)f->title,
WS_CHILD | WS_VISIBLE | SS_RIGHT,
0, 0, 0, 0,
v->hwndCont, NULL, v->hInst, NULL);
SendMessage(v->hwndLabel[i], WM_SETFONT, (WPARAM)hfnt,
MAKELPARAM(1, 0));
v->hwndEdit[i] = CreateWindowEx(
WS_EX_CLIENTEDGE, "EDIT", (LPCTSTR)NULL,
WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL,
0, 0, 0, 0,
v->hwndCont, NULL, v->hInst, NULL);
SendMessage(v->hwndEdit[i], WM_SETFONT, (WPARAM)hfnt,
MAKELPARAM(1, 0));
}
}
BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND :
switch (LOWORD (wParam)) {
case IDOK:
case IDCANCEL:
EndDialog (hDlg, 0);
return TRUE ;
}
break;
}
return FALSE;
}
LRESULT CALLBACK ContWndProc(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam)
{
int iVertPos, iHorzPos;
SCROLLINFO si;
RECT rect;
static VARS *v;
HWND hwndParent;
switch (msg) {
case WM_CREATE:
v = (VARS*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
break;
case WM_VSCROLL:
// Get all the vertical scroll bar information
si.cbSize = sizeof (si) ;
si.fMask = SIF_ALL ;
GetScrollInfo (hwnd, SB_VERT, &si);
// Save the position for comparison later on
iVertPos = si.nPos ;
switch (LOWORD (wParam)) {
case SB_TOP:
si.nPos = si.nMin;
break ;
case SB_BOTTOM:
si.nPos = si.nMax;
break ;
case SB_LINEUP:
si.nPos -= 1;
break ;
case SB_LINEDOWN:
si.nPos += 1;
break ;
case SB_PAGEUP:
si.nPos -= si.nPage;
break ;
case SB_PAGEDOWN:
si.nPos += si.nPage;
break ;
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break ;
default:
break ;
}
// Set the position and then retrieve it. Due to adjustments
// by Windows it may not be the same as the value set.
si.fMask = SIF_POS;
SetScrollInfo (v->hwndCont, SB_VERT, &si, TRUE);
GetScrollInfo (v->hwndCont, SB_VERT, &si);
// If the position has changed, scroll the window
if (si.nPos != iVertPos) {
ScrollWindow(hwnd, 0, v->cyChar * (iVertPos - si.nPos),
NULL, NULL);
UpdateWindow(hwnd);
}
break;
case WM_HSCROLL:
// Get all the horizontal scroll bar information
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
// Save the position for comparison later on
GetScrollInfo (hwnd, SB_HORZ, &si);
iHorzPos = si.nPos;
switch (LOWORD (wParam)) {
case SB_LINELEFT:
si.nPos -= 1;
break;
case SB_LINERIGHT:
si.nPos += 1;
break;
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break ;
default:
break;
}
// Set the position and then retrieve it. Due to adjustments
// by Windows it may not be the same as the value set
si.fMask = SIF_POS;
SetScrollInfo (hwnd, SB_HORZ, &si, TRUE);
GetScrollInfo (hwnd, SB_HORZ, &si);
// If the position has changed, scroll the window
if (si.nPos != iHorzPos) {
ScrollWindow(hwnd, v->cxChar * (iHorzPos - si.nPos), 0,
NULL, NULL);
UpdateWindow(hwnd);
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam)
{
int i, iVertPos, iHorzPos;
WORD id, wScrollNotify;
static int cxClient, cyClient, iMaxWidth;
HDC hdc;
SCROLLINFO si;
RECT rect;
PAINTSTRUCT ps ;
HWND focus;
static HWND oldFocus;
TEXTMETRIC tm;
static VARS *v;
char *p;
switch (msg) {
case WM_CREATE:
v = (VARS*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
hdc = GetDC(hwnd);
SelectObject(hdc, (HGDIOBJ)GetStockObject(ANSI_VAR_FONT));
GetTextMetrics (hdc, &tm);
v->cxChar = tm.tmAveCharWidth;
v->cyChar = tm.tmHeight + tm.tmExternalLeading;
v->xScale = (float)v->cxChar / 7.0;
v->yScale = (float)v->cyChar / 16.0;
v->xMax *= v->xScale;
v->yMax *= v->yScale;
ReleaseDC(hwnd, hdc);
v->hwndStatus = CreateStatusWnd(v->hInst, hwnd, 2);
CreateChildren(v, hwnd);
break;
case WM_SIZE:
ResizeChildren(v);
SendMessage(v->hwndStatus, WM_SIZE, wParam, lParam);
SetStatusParts(v->hwndStatus, 2);
GetClientRect(v->hwndCont, &rect);
cxClient = rect.right;
cyClient = rect.bottom;
// Set vertical scroll bar range and page size
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = (v->yMax + 40) / v->cyChar;
si.nPage = cyClient / v->cyChar;
SetScrollInfo (v->hwndCont, SB_VERT, &si, TRUE);
// Set horizontal scroll bar range and page size
si.cbSize = sizeof (si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = v->xMax / v->cxChar;
si.nPage = cxClient / v->cxChar;
SetScrollInfo(v->hwndCont, SB_HORZ, &si, TRUE);
// Show scroll bars in case they were hidden
ShowScrollBar(v->hwndCont, SB_VERT, TRUE);
ShowScrollBar(v->hwndCont, SB_HORZ, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
// Get vertical scroll bar position
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
GetScrollInfo(v->hwndCont, SB_VERT, &si);
iVertPos = si.nPos;
// Get horizontal scroll bar position
GetScrollInfo (v->hwndCont, SB_HORZ, &si);
iHorzPos = si.nPos;
// Move controls
MoveControls(v, iHorzPos * v->cxChar, iVertPos * v->cyChar);
EndPaint(hwnd, &ps);
break;
case WM_COMMAND:
id = LOWORD(wParam);
switch (id) {
case IDM_EXIT:
PostQuitMessage(0);
break;
case IDM_ADD:
if (! v->sqlCmdActive)
AddRow(v);
break;
case IDM_UPDATE:
if (! v->sqlCmdActive)
UpdateRow(v);
break;
case IDM_DELETE:
if (! v->sqlCmdActive)
DeleteRow(v);
break;
case IDM_CLEAR:
ClearFields(v);
break;
case IDM_SEARCH:
if (! v->sqlCmdActive)
_beginthread(Search, 0, (void*)v);
break;
case IDM_ORDERBY:
OrderBy(v);
break;
case IDM_SQLCMD:
if (! v->sqlCmdActive) {
if ((p = GetInput(v->hwndMain, "SQL Command",
v->sqlCmd, 600))) {
strcpy(v->sqlCmd, p);
_beginthread(SQLCmd, 0, (void*)v);
}
}
break;
case IDM_FIRST:
case IDM_PREV:
case IDM_NEXT:
case IDM_LAST:
if (! v->sqlCmdActive)
GetRow(v, id - IDM_FIRST);
break;
case IDM_ABOUT:
DialogBox(v->hInst, "AboutBox", v->hwndMain,
AboutDlgProc);
break;
case ID_SB_PAGEUP:
case ID_SB_PAGEDOWN:
case ID_SB_TOP:
case ID_SB_BOTTOM:
switch (id) {
case ID_SB_PAGEUP:
wScrollNotify = SB_PAGEUP;
break;
case ID_SB_PAGEDOWN:
wScrollNotify = SB_PAGEDOWN;
break;
case ID_SB_TOP:
wScrollNotify = SB_TOP;
break;
case ID_SB_BOTTOM:
wScrollNotify = SB_BOTTOM;
break;
}
SendMessage(v->hwndCont, WM_VSCROLL,
MAKELONG(wScrollNotify, 0), 0L);
break;
case ID_FOCUS_NEXT:
case ID_FOCUS_PREV:
if ((focus = GetFocus())) {
for (i = 0; i < v->nFields; i++) {
if (focus == v->hwndEdit[i])
break;
}
if (id == ID_FOCUS_NEXT) {
if ((++i) == 15)
i = 0;
} else {
if ((--i) == -1)
i = 14;
}
SetFocus(v->hwndEdit[i]);
}
break;
case ID_TOTITLE:
ToTitle(v);
break;
case ID_TOUPPER:
ToUpper(v);
break;
}
if (v->CheckExtraAccel)
v->CheckExtraAccel(id, v);
break;
case WM_ACTIVATE:
if (LOWORD(wParam) == WA_INACTIVE)
oldFocus = GetFocus();
else
if (oldFocus)
SetFocus(oldFocus);
break;
case WM_CLOSE:
if (! Prompt(hwnd, "SQLBase",
"Do you really want to quit?", 1))
break;
DestroyWindow(hwnd);
break;
case WM_DESTROY:
SavePlacement(hwnd, "Software\\SQLBase");
SetRegVal("Software\\SQLBase", "SQLCmd", (void*)(v->sqlCmd),
strlen(v->sqlCmd));
SQLDisconnect(0);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
static VARS* Init(HINSTANCE hInst, LPSTR cmdLine, INT nCmdShow)
{
WNDCLASS wc;
HWND hwnd;
HMENU hMenu;
VARS *v;
RECT rect;
int i, x = CW_USEDEFAULT, y = 0, w = CW_USEDEFAULT, h = 0;
v = (VARS*)malloc(sizeof(VARS));
v->hInst = hInst;
v->result = NULL;
v->numRows = 0;
v->sqlCmdActive = FALSE;
v->sqlResWndReg = FALSE;
v->lastWidth = v->lastHeight = 0;
memset(v->sqlCmd, 0, 4096);
if (! GetRegVal("Software\\SQLBase", "SQLCmd", (void*)(v->sqlCmd),
4096)) {
strcpy(v->sqlCmd, "");
}
if (! InitDB(v, cmdLine))
return NULL;
if (! LoadLibrary("riched20.dll")) {
MessageBox(NULL, "Couldn't load riched20.dll", "SQLBase",
MB_OK | MB_ICONERROR);
return NULL;
}
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInst, "Icon");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName = "MainMenu";
wc.lpszClassName = "MainWndClass";
if (! RegisterClass(&wc))
return NULL;
wc.lpfnWndProc = (WNDPROC)ContWndProc;
wc.lpszClassName = "ContWndClass";
wc.lpszMenuName = (HMENU)NULL;
if (! RegisterClass(&wc))
return NULL;
if (GetPlacement("Software\\SQLBase", &rect)) {
x = rect.left;
y = rect.top;
w = rect.right - rect.left;
h = rect.bottom - rect.top;
}
v->hwndMain = CreateWindow(
"MainWndClass", v->title,
WS_OVERLAPPEDWINDOW,
x, y, w, h,
NULL, NULL, hInst, (LPVOID)v);
if (v->extraMenuItems && v->extraMenuItems[0].title) {
hMenu = GetMenu(v->hwndMain);
for (i = 0; v->extraMenuItems[i].title; i++) {
InsertMenu(hMenu, IDM_ADD, MF_BYCOMMAND | MF_STRING,
v->extraMenuItems[i].id,
v->extraMenuItems[i].title);
}
InsertMenu(hMenu, IDM_ADD, MF_BYCOMMAND | MF_SEPARATOR, 0, NULL);
}
ShowWindow(v->hwndMain, nCmdShow);
SetFocus(v->hwndEdit[0]);
return v;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
MSG msg;
HWND hwnd;
VARS *v;
if (! (v = Init(hInstance, lpCmdLine, nCmdShow)))
return 0;
if (! (v->hAccel = DefineAccel(v)))
return 0;
while (GetMessage(&msg, (HWND)NULL, 0, 0)) {
if (! TranslateAccelerator(v->hwndMain, v->hAccel, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
DestroyAcceleratorTable(v->hAccel);
return msg.wParam;
}