RESULTS.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:32k
源码类别:
Windows编程
开发平台:
Visual C++
- //*---------------------------------------------------------------------------------
- //| ODBC System Administrator
- //|
- //| This code is furnished on an as-is basis as part of the ODBC SDK and is
- //| intended for example purposes only.
- //|
- //| Title: RESULTS.C
- //| This module contains functions which allow you to view results via an
- //| owner-drawn list box. Having the list box functionality made it easy
- //| to implement Pipes, but has some serious draw-backs as far as record
- //| limits, storage methods, etc... If you are looking for a great way to
- //| paint data in a grid, check out the C++ or Cursor Demo samples that came
- //| with this SDK.
- //*---------------------------------------------------------------------------------
- #include <stdio.h>
- #include "errcheck.h"
- #include "standard.h"
- #include "results.h"
- #include "math.h"
- #include "ini.h"
- //------------------------------------------------------------------------
- // Defines
- //------------------------------------------------------------------------
- VSZFile;
- //------------------------------------------------------------------------
- // Globals
- //------------------------------------------------------------------------
- char szErrMsg[100];
- dCSEG(char) szONE[] = "1";
- dCSEG(char) szZERO[] = "0";
- dCSEG(char) szdate[] = "%02u/%02u/%02u";
- dCSEG(char) sztime[] = "%02u:%02u:%02u";
- dCSEG(char) sztimestmp[] = "%02u/%02u/%02u %02u:%02u:%02u.%lu";
- dCSEG(char) szTypeNotFound[] = "Not found";
- dCSEG(char) szMaxRowsFetched[] = "Maximum rows fetched. Total rows: %lu";
- struct {
- SWORD type; // Data type value
- LPSTR sztype; // String equivalent
- } SqlTypes[] = {
- // type sztype
- // ------------------- -----------------------------
- SQL_BIGINT, "SQL_BIGINT=-5",
- SQL_BINARY, "SQL_BINARY=-2",
- SQL_BIT, "SQL_BIT=-7",
- SQL_CHAR, "SQL_CHAR=1",
- SQL_DATE, "SQL_DATE=9",
- SQL_DECIMAL, "SQL_DECIMAL=3",
- SQL_DOUBLE, "SQL_DOUBLE=8",
- SQL_FLOAT, "SQL_FLOAT=6",
- SQL_INTEGER, "SQL_INTEGER=4",
- SQL_LONGVARBINARY, "SQL_LONGVARBINARY=-4",
- SQL_LONGVARCHAR, "SQL_LONGVARCHAR=-1",
- SQL_NUMERIC, "SQL_NUMERIC=2",
- SQL_REAL, "SQL_REAL=7",
- SQL_SMALLINT, "SQL_SMALLINT=5",
- SQL_TIME, "SQL_TIME=10",
- SQL_TIMESTAMP, "SQL_TIMESTAMP=11",
- SQL_TINYINT, "SQL_TINYINT=-6",
- SQL_VARBINARY, "SQL_VARBINARY=-3",
- SQL_VARCHAR, "SQL_VARCHAR=12",
- };
- struct {
- SWORD type; // Data type value
- LPSTR sztype; // String equivalent
- } CTypes[] = {
- // type sztype
- // ------------------- -----------------------------
- SQL_C_BINARY, "SQL_C_BINARY=-2",
- SQL_C_BIT, "SQL_C_BIT=-7",
- SQL_C_CHAR, "SQL_C_CHAR=1",
- SQL_C_DATE, "SQL_C_DATE=9",
- SQL_C_DOUBLE, "SQL_C_DOUBLE=8",
- SQL_C_FLOAT, "SQL_C_FLOAT=7",
- SQL_C_LONG, "SQL_C_LONG=4",
- SQL_C_SHORT, "SQL_C_SHORT=5",
- SQL_C_TIME, "SQL_C_TIME=10",
- SQL_C_TIMESTAMP, "SQL_C_TIMESTAMP=11",
- SQL_C_TINYINT, "SQL_C_TINYINT=-6",
- };
- typedef struct tagDATATYPE{
- SWORD type; // Data type value
- LPSTR sztype; // String equivalent
- } DATATYPE;
- //------------------------------------------------------------------------
- // Local function prototypes
- //------------------------------------------------------------------------
- void CheckDisplayMode(LPSTR strin, SDWORD cbin, LPSTR strout);
- BOOL INTFUN DrawRow(DRAWITEMSTRUCT FAR * dw,
- RESULTSSET FAR * rs, int xLeftCol, int xRightCol, BOOL fSelect);
- //*------------------------------------------------------------------------
- //| CreateResultsSet:
- //| This is the first function that should be called to create a
- //| results set. When there is no more use for the results set,
- //| call DeleteResultsSet to delete it.
- //|
- //| Parameters:
- //| in rs Pointer to a new results set
- //| in hwndClient Client window
- //| in hInst Instance handle of caller
- //| in count How many columns in the results set
- //| in szTitle Title for the window
- //|
- //| Returns:
- //| TRUE if there were no errors,
- //| FALSE otherwise
- //*------------------------------------------------------------------------
- BOOL EXTFUN CreateResultsSet(RESULTSSET FAR * rs, HWND hwndClient, HINSTANCE hInst,
- int count, LPSTR szTitle)
- {
- if(!rs ||
- count <=0)
- return FALSE;
- memset(rs, 0, sizeof(RESULTSSET));
- rs->cbColumns = count;
- rs->hInst = hInst;
- rs->hwndClient = hwndClient;
- if(*szTitle)
- lstrcpy(rs->szTitle, szTitle);
- rs->md = (METADATA FAR *)GetMemory(sizeof(METADATA) * count);
- if(!rs->md)
- return FALSE;
- return TRUE;
- }
- //*------------------------------------------------------------------------
- //| SetMetaDataColumn:
- //| This function must be called for each column in the results set. The
- //| information placed for each row can be obtained using ODBC functions
- //| such as SQLDescribeCol and SQLColAttribute.
- //| Parameters:
- //| in rs Pointer to a results set
- //| in iCol Column number
- //| in szCol Pointer to column name
- //| in szTypeName Data type name
- //| in fSqlType ODBC data type number
- //| in precision Precision
- //| in scale Scale
- //| in cbDisplay Display size
- //| in fAlign Alignment
- //| Returns:
- //| Nothing
- //*------------------------------------------------------------------------
- BOOL EXTFUN SetMetaDataColumn(RESULTSSET FAR * rs, int iCol, LPSTR szCol,
- LPSTR szTypeName, SDWORD fSqlType, UDWORD precision, SWORD scale,
- int cbDisplay, UINT fAlign)
- {
- if(!rs ||
- iCol < 0 ||
- !szCol ||
- !*szCol ||
- !szTypeName ||
- !*szTypeName) {
- PostError((LPSTR)szInvalidParms);
- return FALSE;
- }
- rs->md[iCol].szColumnName = (LPSTR)GetMemory(lstrlen(szCol)+1);
- if(!rs->md[iCol].szColumnName)
- return FALSE;
- precision = min(precision, MAXBYTES);
- lstrcpy(rs->md[iCol].szColumnName, szCol);
- lstrcpy(rs->md[iCol].szTypeName, szTypeName);
- rs->md[iCol].fSqlType = fSqlType;
- rs->md[iCol].precision = precision;
- rs->md[iCol].scale = scale;
- rs->md[iCol].cbDisplaySize = cbDisplay;
- rs->md[iCol].fAlign = fAlign;
- rs->md[iCol].cbOffset = (iCol > 0) ? (UINT)(precision + rs->md[iCol-1].cbOffset) : (UINT)(precision);
- ++rs->md[iCol].cbOffset; // Room for terminators
- return TRUE;
- }
- //*------------------------------------------------------------------------
- //| AllocateRowData:
- //| Call this function for each row in the results set to allocate
- //| memory and insert a row into the results set.
- //| Parameters:
- //| in rs Pointer to results set
- //| in rd Pointer to a row data structure
- //| in cColor Text color
- //| in cBkg Background color
- //| Returns:
- //| Pointer to a ROWDATA structure
- //*------------------------------------------------------------------------
- ROWDATA FAR * AllocateRowData(RESULTSSET FAR * rs, COLORREF cColor, COLORREF cBkg)
- {
- ROWDATA FAR * rd;
- int dex;
- if(!rs) {
- PostError((LPSTR)szInvalidParms);
- return FALSE;
- }
- rd = (ROWDATA FAR *)GetMemory(sizeof(ROWDATA));
- if(!rd)
- return NULL;
- rd->textColor = cColor;
- rd->bkgrnd = cBkg;
- rd->cd = (COLUMNDATA FAR *)GetMemory((sizeof(COLUMNDATA) * rs->cbColumns));
- if(!rd->cd)
- return NULL;
- rd->data = (LPSTR)GetMemory(rs->md[rs->cbColumns-1].cbOffset + 1);
- if(!rd->data)
- return NULL;
- rd->cd[0].szCols = rd->data;
- for(dex=1; dex<rs->cbColumns; dex++)
- rd->cd[dex].szCols = rd->data + rs->md[dex-1].cbOffset;
- return rd;
- }
- //*------------------------------------------------------------------------
- //| SetColumnData:
- //| Call this function for a particular column in a ROWDATA structure.
- //| If memory has been allocated for the column, it will be freed
- //| and reallocated for the new string.
- //| Parameters:
- //| in icol Which column?
- //| in rd Pointer to a row data structure
- //| in str Pointer to the new buffer
- //| Returns:
- //| TRUE if successful
- //| FALSE on error
- //*------------------------------------------------------------------------
- BOOL EXTFUN SetColumnData(int icol, ROWDATA FAR * rd, LPSTR str)
- {
- if(!str ||
- !*str)
- return FALSE;
- lstrcpy(rd->cd[icol].szCols, str);
- return TRUE;
- }
- //*------------------------------------------------------------------------
- //| FreeRowData:
- //| Pass a pointer to the ROWDATA structure to free. Obviously since
- //| you are asked for a RESULTSSET pointer, you should call this
- //| function before freeing the results set data.
- //| Parms:
- //| in rs Pointer to results set
- //| in rd Pointer to row data
- //| Returns:
- //| Nothing.
- //*------------------------------------------------------------------------
- void EXTFUN FreeRowData(RESULTSSET FAR * rs, ROWDATA FAR * rd)
- {
- ReleaseMemory(rd->data);
- ReleaseMemory((LPVOID)rd->cd);
- ReleaseMemory((LPVOID)rd);
- }
- //*------------------------------------------------------------------------
- //| FreeResultsSet:
- //| Call this function to free all of the memory for a results set.
- //| Parms:
- //| in rs Pointer to results set data to free
- //| Returns:
- //| TRUE If successful
- //| FALSE if there was an error
- //*------------------------------------------------------------------------
- void EXTFUN FreeResultsSet(RESULTSSET FAR * rs)
- {
- int dex;
- DeleteObject(rs->hFont);
- for(dex=0; dex<rs->cbColumns; dex++)
- ReleaseMemory(rs->md[dex].szColumnName);
- ReleaseMemory(rs->md);
- ReleaseMemory(rs);
- return;
- }
- //*------------------------------------------------------------------------
- //| CreateResultsFont:
- //| This function is called to create a font for the results set. The
- //| default font is used if the lf parameter is NULL. Alternatively
- //| the user can pass in a complete LOGFONT structure to use for the
- //| font.
- //| Parms:
- //| in rs Pointer to results set to store info
- //| in hwnd Window handle to verify font
- //| in lf LOGFONT structure to use, NULL for dft
- //| Returns:
- //| Nothing.
- //*------------------------------------------------------------------------
- void CreateResultsFont(RESULTSSET FAR * rs, HWND hwnd, LOGFONT FAR * lf)
- {
- HDC hdc;
- LOGFONT logfont;
- HFONT hf;
- TEXTMETRIC tm;
- SIZE sz;
- int tmp, dex, cbExtra;
- if(!lf) {
- memset(&logfont, 0, sizeof(LOGFONT));
- GetDefaultFont(&logfont);
- }
- else
- memmove(&logfont, lf, sizeof(LOGFONT));
- rs->hFont = CreateFontIndirect(&logfont);
- hdc = GetDC(hwnd);
- hf = SelectObject(hdc, rs->hFont);
- GetTextMetrics(hdc, &tm);
- rs->cx = tm.tmAveCharWidth;
- rs->cy = tm.tmHeight + tm.tmExternalLeading;
- cbExtra = GetSystemMetrics(SM_CYBORDER);
- rs->cTitleHeight = rs->cy + (7 * cbExtra);
- rs->yTitleLoc = (rs->cTitleHeight / 2) + rs->cy;
- for(dex=0, tmp=0; dex<rs->cbColumns; dex++) {
- GetTextExtentPoint(hdc, rs->md[dex].szColumnName,
- lstrlen(rs->md[dex].szColumnName), &sz);
- rs->md[dex].cColWidth = (rs->md[dex].cbDisplaySize * rs->cx) + (7 * cbExtra);
- rs->md[dex].cColWidth = max((UINT)(sz.cx * 1.5),
- rs->md[dex].cColWidth);
- rs->md[dex].xCol = tmp;
- tmp += rs->md[dex].cColWidth;
- }
- rs->cRowWidth = tmp;
- SelectObject(hdc,hf);
- ReleaseDC(hwnd, hdc);
- }
- //*------------------------------------------------------------------------
- //| FindRightCol:
- //| This function will take the left column and a results set descriptor
- //| and return the right column index based on what will fit in the
- //| window.
- //| Parms:
- //| in rs Pointer to results set to store info
- //| in xLeftCol Current left column index
- //| in cWidth Available width
- //| Returns:
- //| Index to be used for right column
- //*------------------------------------------------------------------------
- int FindRightCol(RESULTSSET FAR * rs, int xLeftCol, int cWidth)
- {
- int xRightCol;
- int cSpace;
- xRightCol = xLeftCol;
- cSpace = cWidth - rs->md[xLeftCol].cColWidth;
- while(cSpace>0 &&
- xRightCol < rs->cbColumns-1) {
- ++xRightCol;
- cSpace -= rs->md[xRightCol].cColWidth;
- }
- return xRightCol;
- }
- //*------------------------------------------------------------------------
- //| DrawRowData:
- //| This function will do the actual drawing on the screen based on the
- //| control structures passed in.
- //| Parms:
- //| in rs Pointer to results set to store info
- //| in dwitem Draw structure
- //| in xLeftCol Current left column index
- //| in xRightCol Right column index
- //| Returns:
- //| Nothing.
- //*------------------------------------------------------------------------
- void DrawRowData(RESULTSSET FAR * rs, DRAWITEMSTRUCT FAR * dwitem,
- int xLeftCol, int xRightCol)
- {
- switch(dwitem->itemAction) {
- case ODA_DRAWENTIRE:
- case ODA_SELECT:
- DrawRow(dwitem, rs, xLeftCol, xRightCol,
- (dwitem->itemState == ODS_SELECTED));
- return;
- }
- }
- //*------------------------------------------------------------------------
- //| DrawColumnTitles:
- //| This function is called when we need to paint the column titles for a
- //| results set. We will simply write them out.
- //| Parms:
- //| in hdc Handle to our device contex
- //| in rs Our results set to draw
- //| in crect Client rectangle to paint in
- //| in xLeftCol Left column
- //| in xRightCol Right column
- //| Returns:
- //| Nothing.
- //*------------------------------------------------------------------------
- void INTFUN DrawColumnTitles(HDC hdc, RESULTSSET FAR * rs,
- RECT FAR * crect, int xLeftCol, int xRightCol)
- {
- int dex, offset, cright=0;
- RECT rect;
- HFONT hf;
- hf = SelectObject(hdc, rs->hFont);
- SetTextColor(hdc, RDATA_BLACK);
- offset = 0 - rs->md[xLeftCol].xCol;
- for (dex=xLeftCol; dex<=xRightCol; dex++)
- cright += rs->md[dex].cColWidth;
- Rectangle(hdc, crect->left, crect->top, min(cright, crect->right), crect->bottom+1);
- SetBkColor(hdc, RDATA_GRAY);
- rect.top = crect->top +1;
- rect.bottom = crect->bottom;
- for(dex=xLeftCol; dex<=xRightCol; dex++) {
- rect.left = rs->md[dex].xCol + offset;
- rect.right = rect.left + rs->md[dex].cColWidth;
- MoveTo(hdc, rect.right, rect.top);
- LineTo(hdc, rect.right, rect.bottom);
- ++rect.left;
- #ifdef TITLE_DEBUG
- {
- char tmpbuff[50];
- wsprintf(tmpbuff, "Column: %d, left=%d, top=%d, right=%d, bottom=%d",
- dex,
- rect.left, rect.top,
- rect.right, rect.bottom);
- DrawFocusRect(hdc, &rect);
- MessageBox(NULL, (LPSTR)tmpbuff, "Debug", MB_OK);
- DrawFocusRect(hdc, &rect);
- }
- #endif
- ExtTextOut(hdc, rs->md[dex].xCol + 3 + offset, rect.top + 4,
- ETO_CLIPPED | ETO_OPAQUE,
- &rect,
- rs->md[dex].szColumnName,
- lstrlen(rs->md[dex].szColumnName),
- NULL);
- }
- SelectObject(hdc,hf); // change font back
- }
- //*------------------------------------------------------------------------
- //| DrawRow:
- //| Call this function for each row which must be painted.
- //| Parms:
- //| in dw Draw structure
- //| in rs Our results set to draw
- //| in xLeftCol Index to left-most column displayed
- //| in xRightCol Index to right-most column displayed
- //| in fSelect Is the item supposed to be selected?
- //| Returns:
- //| TRUE if successful,
- //| FALSE otherwise
- //*------------------------------------------------------------------------
- //#define RECT_DEBUG
- BOOL INTFUN DrawRow(DRAWITEMSTRUCT FAR * dw,
- RESULTSSET FAR * rs,
- int xLeftCol, int xRightCol,
- BOOL fSelect)
- {
- ROWDATA FAR * rd=(ROWDATA FAR *)dw->itemData;
- int dex;
- int offset;
- int cright=0;
- RECT rect;
- HFONT hf;
- //
- // First set the font and text colors according to the user's request, then draw
- // a line at the bottom of the row for a separator. Note that the rcItem
- // rectangle passed to us in the DRAWITEMSTRUCT is for the
- //
- hf = SelectObject(dw->hDC, rs->hFont);
- dw->rcItem.right = min(rs->cRowWidth, dw->rcItem.right);
- for (dex=xLeftCol; dex<=xRightCol; dex++)
- cright += rs->md[dex].cColWidth;
- // Draw top of box
- MoveTo(dw->hDC, dw->rcItem.left, dw->rcItem.top);
- LineTo(dw->hDC, min(cright, dw->rcItem.right), dw->rcItem.top);
- // Draw bottom also, to take care of last line
- MoveTo(dw->hDC, dw->rcItem.left, dw->rcItem.bottom);
- LineTo(dw->hDC, min(cright, dw->rcItem.right), dw->rcItem.bottom);
- #ifdef RECT_DEBUG
- {
- char tmpbuff[50];
- wsprintf(tmpbuff, "dw->rcItem, left=%d, top=%d, right=%d, bottom=%d",
- dw->rcItem.left, dw->rcItem.top,
- dw->rcItem.right, dw->rcItem.bottom);
- DrawFocusRect(dw->hDC, &dw->rcItem);
- MessageBox(NULL, (LPSTR)tmpbuff, "Debug", MB_OK);
- DrawFocusRect(dw->hDC, &dw->rcItem);
- }
- #endif
- //
- // Now loop through each column in the row and draw it's contents by creating
- // a logical rectangle for each column, then filling in that rectangle with
- // the value to be displayed.
- //
- rect.top = dw->rcItem.top+1;
- rect.bottom = dw->rcItem.bottom;
- SetBkMode(dw->hDC, TRANSPARENT);
- if(fSelect) {
- SetBkColor(dw->hDC, GetSysColor(COLOR_HIGHLIGHT));
- SetTextColor(dw->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
- }
- else {
- SetBkColor(dw->hDC, rd->bkgrnd);
- SetTextColor(dw->hDC, rd->textColor);
- }
- offset = 0 - rs->md[xLeftCol].xCol;
- for (dex=xLeftCol; dex<=xRightCol; dex++) {
- rect.left = offset + rs->md[dex].xCol;
- rect.right = rect.left + rs->md[dex].cColWidth;
- MoveTo(dw->hDC, rect.right, rect.top);
- LineTo(dw->hDC, rect.right, rect.bottom);
- #ifdef RECT_DEBUG
- {
- char tmpbuff[50];
- wsprintf(tmpbuff, "Column: %d, left=%d, top=%d, right=%d, bottom=%d",
- dex,
- rect.left, rect.top,
- rect.right, rect.bottom);
- DrawFocusRect(dw->hDC, &rect);
- MessageBox(NULL, (LPSTR)tmpbuff, "Debug", MB_OK);
- DrawFocusRect(dw->hDC, &rect);
- }
- #endif
- SetTextAlign(dw->hDC, rs->md[dex].fAlign);
- if(dex != xLeftCol)
- ++rect.left;
- ExtTextOut(dw->hDC, rs->md[dex].xCol + 3 + offset, rect.top + 4,
- ETO_CLIPPED | ETO_OPAQUE,
- &rect,
- rd->cd[dex].szCols,
- lstrlen(rd->cd[dex].szCols),
- NULL);
- }
- SelectObject(dw->hDC,hf); // change font back
- return TRUE;
- }
- //*------------------------------------------------------------------------
- //| HandleHScroll:
- //| This function adds a new item to our results set.
- //| Parms:
- //| in wParam Scroll option
- //| in rs Results set pointer
- //| in hwnd Window handle for column title
- //| in hwndHScroll Scroll bar window handle
- //| in xLeftCol Left column index
- //| in xRightCol Right column index
- //| in hwndList Listbox window handle
- //| in cbColumns Number of columns
- //| in cbClient Width of screen available to draw in
- //| in tRect Bounding rectangle for client window
- //| Returns:
- //| Index to string if successful, LB_ERRSPACE otherwise
- //*------------------------------------------------------------------------
- void HandleHScroll(WPARAM wParam, RESULTSSET FAR * rs,
- HWND hwnd, HWND hwndHScroll, int FAR * xLeftCol, int FAR * xRightCol,
- HWND hwndList, int cbColumns, int cbClient, RECT FAR * tRect)
- {
- int cHScrollPos;
- int fhScroll=FALSE;
- cHScrollPos = GetScrollPos(hwndHScroll, SB_CTL);
- switch(wParam) {
- case SB_LINEUP: // Shift right one column
- if(!*xLeftCol)
- fhScroll = FALSE;
- else {
- --cHScrollPos;
- fhScroll = TRUE;
- --*xLeftCol;
- }
- break;
- case SB_LINEDOWN: // Shift left one column
- if(*xLeftCol+1 == cbColumns)
- fhScroll = FALSE; // No change required
- else {
- ++cHScrollPos;
- fhScroll = TRUE;
- ++*xLeftCol;
- }
- break;
- case SB_PAGEUP: // Shift right one screen
- if(!*xLeftCol)
- fhScroll = FALSE;
- else {
- --cHScrollPos;
- fhScroll = TRUE;
- --*xLeftCol;
- }
- break;
- case SB_PAGEDOWN: // Shift left one screen
- if(*xLeftCol+1 == cbColumns)
- fhScroll = FALSE; // No change required
- else {
- if(*xLeftCol < *xRightCol) {
- cHScrollPos += *xRightCol - *xLeftCol;
- *xLeftCol = *xRightCol;
- fhScroll = TRUE;
- }
- else {
- ++cHScrollPos;
- ++*xLeftCol;
- fhScroll = TRUE;
- }
- }
- break;
- case SB_THUMBPOSITION: // Specific location
- break;
- }
- //
- // If movement is required, we will have adjusted the scroll position
- // and columns already. Calculate what columns will fit on our current
- // display to find the rightmost column. Next invalidate the areas
- // requiring painting and set the new scroll position. This will cause
- // each row to be redrawn starting with the new rwi->xLeftCol.
- //
- if(fhScroll) { // Movement is required
- RECT rect;
- *xRightCol = FindRightCol(rs, *xLeftCol, cbClient);
- GetClientRect(hwndList, &rect);
- InvalidateRect(hwndList, &rect, TRUE);
- SetScrollPos(hwndHScroll, SB_CTL, cHScrollPos, TRUE);
- InvalidateRect(hwnd, tRect, TRUE);
- }
- }
- //*------------------------------------------------------------------------
- //| HandleVirtualHScroll:
- //| This function should be called in response to the WM_KEYDOWN
- //| message. It will look for a virtual key to see if the user
- //| is trying to do scrolling. If so, we will force the scroll
- //| to happen.
- //| Parms:
- //| in wParam Value of wParam for WM_KEYDOWN
- //| in hwndList Handle of list box
- //| in hwndOwner Owner window of the horizontal scrollbar
- //| Returns:
- //| Nothing.
- //*------------------------------------------------------------------------
- void HandleVirtualHScroll(WPARAM wParam, HWND hwndList, HWND hwndOwner)
- {
- switch(wParam) {
- case VK_HOME:
- SendMessage(hwndList, WM_VSCROLL, SB_TOP, 0L);
- return;
- case VK_END:
- SendMessage(hwndList, WM_VSCROLL, SB_BOTTOM, 0L);
- return;
- case VK_PRIOR:
- SendMessage(hwndList, WM_VSCROLL, SB_PAGEUP, 0L);
- return;
- case VK_NEXT:
- SendMessage(hwndList, WM_VSCROLL, SB_PAGEDOWN, 0L);
- return;
- case VK_UP:
- SendMessage(hwndList, WM_VSCROLL, SB_LINEUP, 0L);
- return;
- case VK_DOWN:
- SendMessage(hwndList, WM_VSCROLL, SB_LINEDOWN, 0L);
- return;
- case VK_LEFT:
- SendMessage(hwndOwner, WM_HSCROLL, SB_LINEUP, 0L);
- return;
- case VK_RIGHT:
- SendMessage(hwndOwner, WM_HSCROLL, SB_LINEDOWN, 0L);
- return;
- }
- }
- //*------------------------------------------------------------------------
- //| AddRowData:
- //| This function adds a new item to our results set.
- //| Parms:
- //| in rs Pointer to results set
- //| in rd Pointer to row data to add
- //| Returns:
- //| Index to string if successful, LB_ERRSPACE otherwise
- //*------------------------------------------------------------------------
- int AddRowData(RESULTSSET FAR * rs, ROWDATA FAR * rd)
- {
- int rtn;
- DWORD cbCnt;
- rtn = (int)SendMessage(rs->hwndList, LB_ADDSTRING, 0, (LPARAM)(ROWDATA FAR *)rd);
- if(rtn == LB_ERRSPACE) {
- cbCnt = SendMessage(rs->hwndList, LB_GETCOUNT, 0, 0L);
- wsprintf(szErrMsg, szMaxRowsFetched, cbCnt);
- MessageBox(rs->hwndClient, szErrMsg, szErrTitle, MB_OK);
- }
- return rtn;
- }
- //*------------------------------------------------------------------------
- //| GetNumResultsCols:
- //| Given an hstmt which has an executed statement on it, find the number
- //| of results columns in it.
- //| Parms:
- //| in hstmt Statement handle with results set
- //| Returns:
- //| Number of columns
- //*------------------------------------------------------------------------
- SWORD GetNumResultsCols(HSTMT hstmt)
- {
- SWORD cbCols;
- RETCODE retcode;
- retcode = SQLNumResultCols(hstmt, &cbCols);
- if(RC_NOTSUCCESSFUL(retcode))
- return -1;
- else
- return cbCols;
- }
- //*------------------------------------------------------------------------
- //| GetTypeName:
- //| This function will return the null-terminated character name of
- //| the type passed in.
- //| Parms:
- //| in type SQL_TYPE or C_TYPE
- //| in fType The fCType or fSqlType
- //| Returns:
- //| Nothing.
- //*------------------------------------------------------------------------
- LPSTR GetTypeName(int type, int fType)
- {
- int dex, stopdex;
- DATATYPE FAR * dt;
- if(type == SQL_TYPE) {
- stopdex = NumItems(SqlTypes);
- dt = (DATATYPE FAR *)&SqlTypes;
- }
- else {
- stopdex = NumItems(CTypes);
- dt = (DATATYPE FAR *)&CTypes;
- }
- for(dex=0; dex<stopdex; dex++)
- if(dt[dex].type == fType)
- return dt[dex].sztype;
- return (LPSTR)szTypeNotFound;
- }
- //*------------------------------------------------------------------------
- //| ConvertSqlTypeToChar:
- //| This function will convert the value passed in to it's character equivalent.
- //| Parms:
- //| in rs Pointer to results set
- //| in col Which column is it?
- //| in inbuff Input buffer
- //| in outbuff Output buffer
- //| in rtnd Returned bytes from SQLGetData
- //| Returns:
- //| Nothing.
- //*------------------------------------------------------------------------
- void ConvertSqlTypeToChar(RESULTSSET FAR * rs, int col, LPSTR inbuff,
- LPSTR outbuff, SDWORD rtnd)
- {
- LPSTR tmpstr;
- SWORD FAR * tmpsword;
- SDWORD FAR * tmpsdword;
- SFLOAT FAR * tmpsfloat;
- SDOUBLE FAR * tmpsdouble;
- DATE_STRUCT FAR * tmpdate;
- TIME_STRUCT FAR * tmptime;
- TIMESTAMP_STRUCT FAR * tmptimestmp;
- *outbuff = ' ';
- switch(rs->md[col].fSqlType) {
- //
- // Look for any non-displayable characters and change them to periods
- //
- case SQL_CHAR:
- case SQL_VARCHAR:
- case SQL_LONGVARCHAR:
- CheckDisplayMode((LPSTR)inbuff, rtnd, outbuff);
- tmpstr = outbuff + rtnd;
- *tmpstr = ' ';
- break;
- case SQL_BINARY:
- case SQL_VARBINARY:
- case SQL_LONGVARBINARY:
- lstrcpy(outbuff, "0x");
- BinToChar(outbuff+2, (LPSTR)inbuff, rtnd);
- break;
- case SQL_TINYINT:
- case SQL_SMALLINT:
- tmpsword = (SWORD FAR *)inbuff;
- wsprintf(outbuff, "%d", *tmpsword);
- break;
- case SQL_INTEGER:
- case SQL_BIGINT:
- tmpsdword = (SDWORD FAR *)inbuff;
- wsprintf(outbuff, "%ld", *tmpsdword);
- break;
- case SQL_FLOAT:
- case SQL_DOUBLE:
- tmpsdouble = (SDOUBLE FAR *)inbuff;
- sprintf(outbuff, "%Fg", *tmpsdouble);
- break;
- case SQL_REAL:
- tmpsfloat = (SFLOAT FAR *)inbuff;
- sprintf(outbuff, "%Fg", *tmpsfloat);
- break;
- case SQL_BIT:
- tmpsword = (SWORD FAR *)inbuff;
- lstrcpy(outbuff, (*tmpsword) ? (LPSTR)szONE : (LPSTR)szZERO);
- break;
- case SQL_DECIMAL:
- case SQL_NUMERIC:
- lstrcpy(outbuff, inbuff);
- break;
- case SQL_DATE:
- tmpdate = (DATE_STRUCT FAR *)inbuff;
- wsprintf(outbuff, szdate, tmpdate->month, tmpdate->day, tmpdate->year);
- break;
- case SQL_TIME:
- tmptime= (TIME_STRUCT FAR *)inbuff;
- wsprintf(outbuff, sztime, tmptime->hour, tmptime->minute, tmptime->second);
- break;
- case SQL_TIMESTAMP:
- tmptimestmp = (TIMESTAMP_STRUCT FAR *)inbuff;
- wsprintf(outbuff, sztimestmp, tmptimestmp->year, tmptimestmp->month,
- tmptimestmp->day, tmptimestmp->hour, tmptimestmp->minute,
- tmptimestmp->second, tmptimestmp->fraction);
- break;
- }
- return;
- }
- //*------------------------------------------------------------------------
- //| CheckDisplayMode:
- //| This function looks through a string for the count specified, then
- //| changes any x"00" to a period so it can be displayed.
- //| Parms:
- //| strin - String coming in
- //| cbin - Byte count of incoming string
- //| strout - Output string
- //*------------------------------------------------------------------------
- void CheckDisplayMode(LPSTR strin, SDWORD cbin, LPSTR strout)
- {
- SDWORD dex,max=cbin;
- LPSTR str=strout;
- if(cbin < 0)
- max = lstrlen(strin);
- memcpy(strout, strin, (size_t)max);
- for(dex=0; dex<cbin; dex++, str++)
- if(!*str)
- *str = '.';
- }
- //*------------------------------------------------------------------------
- //| BinToChar:
- //| Takes a string and converts to its hexidecimal equivalent
- //*------------------------------------------------------------------------
- void BinToChar(LPSTR outstr, LPSTR instr, SDWORD count)
- {
- UCHAR uletter;
- LPSTR istr=instr;
- LPSTR ostr=outstr;
- while(count--) {
- uletter = (*instr & 0xF0) >> 4; // High nibble
- if(uletter <= 9)
- *ostr++ = uletter + '0';
- else
- *ostr++ = 'A' + (uletter - 10);
- uletter = *instr++ & 0x0F;
- if(uletter <= 9)
- *ostr++ = uletter + '0';
- else
- *ostr++ = 'A' + (uletter - 10);
- }
- *ostr = ' ';
- }