URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/ecos-2.0/packages/services/gfx/mw/v2_0/src/mwin/winlib
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/caret.c
0,0 → 1,184
/* |
* Copyright (c) 2000 Greg Haerr <greg@censoft.com> |
* |
* Caret control for Microwindows win32 api. |
* |
* TODO: add SetSysTimer for blinking |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <sys/time.h> |
#ifndef __ECOS |
#include <malloc.h> |
#endif |
#include "windows.h" |
#include "device.h" |
|
#define DEF_BLINK_TIME 500 /* default blink time in ms*/ |
|
typedef struct { |
HWND hwnd; /* != NULL if caret is created*/ |
int x; |
int y; |
int nWidth; |
int nHeight; |
BOOL fShown; /* caret is currently visible*/ |
int nShowCount; /* <= 0 for hidden caret*/ |
UINT nBlinkTime; |
} CARETINFO; |
|
/* local data*/ |
static CARETINFO sysCaret; /* the system caret*/ |
|
/* local procs*/ |
static void MwShowCaret(void); |
static void MwHideCaret(void); |
static void MwUpdateCaret(void); |
|
BOOL WINAPI |
CreateCaret(HWND hwnd, HBITMAP hBitmap, int nWidth, int nHeight) |
{ |
|
DestroyCaret(); /* destroy old caret if any*/ |
|
if (nWidth <= 0) |
nWidth = 1; |
if (nHeight <= 0) |
nHeight = 1; |
|
sysCaret.hwnd = hwnd; |
sysCaret.x = 0; |
sysCaret.y = 0; |
sysCaret.nWidth = nWidth; |
sysCaret.nHeight = nHeight; |
sysCaret.fShown = FALSE; |
sysCaret.nShowCount = 0; |
sysCaret.nBlinkTime = DEF_BLINK_TIME; |
return TRUE; |
} |
|
BOOL WINAPI |
DestroyCaret(VOID) |
{ |
if (sysCaret.fShown) |
MwHideCaret(); |
sysCaret.hwnd = NULL; |
sysCaret.fShown = FALSE; |
return TRUE; |
} |
|
BOOL WINAPI |
HideCaret(HWND hwnd) |
{ |
if (hwnd == NULL) |
hwnd = sysCaret.hwnd; |
if (hwnd == NULL || hwnd != sysCaret.hwnd) |
return FALSE; |
|
/* hide caret if this call made it invisible*/ |
if (--sysCaret.nShowCount == 0) { |
MwHideCaret(); |
return TRUE; |
} |
return FALSE; |
} |
|
BOOL WINAPI |
ShowCaret(HWND hwnd) |
{ |
if (hwnd == NULL) |
hwnd = sysCaret.hwnd; |
if (hwnd == NULL || hwnd != sysCaret.hwnd || sysCaret.nShowCount < 0) |
return FALSE; |
|
if (++sysCaret.nShowCount > 1) |
return TRUE; |
|
/* show caret, this call made it visible*/ |
MwShowCaret(); |
return TRUE; |
} |
|
BOOL WINAPI |
SetCaretPos(int nX, int nY) |
{ |
if (sysCaret.fShown && (sysCaret.x != nX || sysCaret.y != nY)) { |
MwUpdateCaret(); /* toggle off*/ |
sysCaret.x = nX; |
sysCaret.y = nY; |
MwUpdateCaret(); /* toggle on in new location*/ |
return TRUE; |
} |
sysCaret.x = nX; |
sysCaret.y = nY; |
return TRUE; |
} |
|
BOOL WINAPI |
GetCaretPos(LPPOINT lpPoint) |
{ |
lpPoint->x = sysCaret.x; |
lpPoint->y = sysCaret.y; |
return TRUE; |
} |
|
UINT WINAPI |
GetCaretBlinkTime(VOID) |
{ |
return sysCaret.nBlinkTime; |
} |
|
BOOL WINAPI |
SetCaretBlinkTime(UINT uMSeconds) |
{ |
sysCaret.nBlinkTime = uMSeconds; |
/* SetSysTimer */ |
return TRUE; |
} |
|
static void |
MwShowCaret(void) |
{ |
if (sysCaret.fShown) |
return; |
MwUpdateCaret(); |
sysCaret.fShown = TRUE; |
} |
|
static void |
MwHideCaret(void) |
{ |
if (!sysCaret.fShown) |
return; |
MwUpdateCaret(); |
sysCaret.fShown = FALSE; |
} |
|
/* Draw the caret using XOR. Same routine is used to show and hide caret.*/ |
static void |
MwUpdateCaret(void) |
{ |
int oldmode; |
HDC hdc; |
HPEN hpen; |
HBRUSH hbr; |
|
oldmode = GdSetMode(MWMODE_XOR); |
hdc = GetDC(sysCaret.hwnd); |
hpen = SelectObject(hdc, GetStockObject(WHITE_PEN)); |
|
/* it seems there's some problems with Rectangle with nWidth == 1*/ |
if (sysCaret.nWidth == 1) { |
MoveToEx(hdc, sysCaret.x, sysCaret.y, NULL); |
LineTo(hdc, sysCaret.x, sysCaret.y+sysCaret.nHeight); |
} else { |
hbr = SelectObject(hdc, GetStockObject(WHITE_BRUSH)); |
Rectangle(hdc, sysCaret.x, sysCaret.y, |
sysCaret.x+sysCaret.nWidth, |
sysCaret.y+sysCaret.nHeight); |
SelectObject(hdc, hbr); |
} |
SelectObject(hdc, hpen); |
ReleaseDC(sysCaret.hwnd, hdc); |
GdSetMode(oldmode); |
} |
/medit.c
0,0 → 1,1744
/* |
* Copyright (C) 1999, 2000, Wei Yongming. |
* Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com> |
* |
* Multi Line Edit Control for Microwindows win32 api. |
*/ |
|
/* |
** This library is free software; you can redistribute it and/or |
** modify it under the terms of the GNU Library General Public |
** License as published by the Free Software Foundation; either |
** version 2 of the License, or (at your option) any later version. |
** |
** This library is distributed in the hope that it will be useful, |
** but WITHOUT ANY WARRANTY; without even the implied warranty of |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
** Library General Public License for more details. |
** |
** You should have received a copy of the GNU Library General Public |
** License along with this library; if not, write to the Free |
** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
** MA 02111-1307, USA |
*/ |
|
/* |
** Alternatively, the contents of this file may be used under the terms |
** of the Mozilla Public License (the "MPL License") in which case the |
** provisions of the MPL License are applicable instead of those above. |
*/ |
|
/* Note: |
** Although there was a version by Zhao Jianghua, this version of |
** EDIT control is written by Wei Yongming from scratch. |
** |
** Create date: 1999/8/26 |
** |
** Modify records: |
** |
** Who When Where For What Status |
**----------------------------------------------------------------------------- |
** WEI Yongming 2000/02/24 Tsinghua Add MPL License Finished |
** Kevin Tseng 2000/08/30 gv port to microwin ported |
** |
** |
** TODO: |
** * Selection. |
** * Undo. |
*/ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <sys/time.h> |
#define MWINCLUDECOLORS |
#include "windows.h" /* windef.h, winuser.h */ |
#include "wintools.h" |
#include "device.h" /* GdGetTextSize */ |
|
#define USE_BIG5 |
|
#define WIDTH_MEDIT_BORDER 2 |
#define MARGIN_MEDIT_LEFT 1 |
#define MARGIN_MEDIT_TOP 1 |
#define MARGIN_MEDIT_RIGHT 2 |
#define MARGIN_MEDIT_BOTTOM 1 |
|
#define LEN_MLEDIT_BUFFER 3000 |
#define LEN_MLEDIT_UNDOBUFFER 1024 |
|
#define EST_FOCUSED 0x00000001L |
#define EST_MODIFY 0x00000002L |
#define EST_READONLY 0x00000004L |
#define EST_REPLACE 0x00000008L |
|
#define MEDIT_OP_NONE 0x00 |
#define MEDIT_OP_DELETE 0x01 |
#define MEDIT_OP_INSERT 0x02 |
#define MEDIT_OP_REPLACE 0x03 |
|
typedef struct tagLINEDATA { |
|
int dataEnd; |
|
|
char buffer[LEN_MLEDIT_BUFFER+1]; |
}LINEDATA; |
typedef LINEDATA* PLINEDATA; |
|
#define ATTENG 0 /* english */ |
#define ATTCHL 1 /* chinese left(1st) byte */ |
#define ATTCHR 2 /* chinese right(2nd) byte */ |
static char attr[LEN_MLEDIT_BUFFER]; |
|
typedef struct tagMLEDITDATA { |
|
|
int editPos; /* current edit position */ |
int caretPos; /* caret offset in box */ |
int editLine; /* current eidt line */ |
|
int StartlineDisp; /* start line displayed */ |
int EndlineDisp; /* end line displayed */ |
|
|
|
|
int selStartPos; /* selection start position */ |
int selStartLine; /* selection start line */ |
int selEndPos; /* selection end position */ |
int selEndLine; /* selection end line */ |
|
int passwdChar; /* password character */ |
|
int leftMargin; /* left margin */ |
int topMargin; /* top margin */ |
int rightMargin; /* right margin */ |
int bottomMargin; /* bottom margin */ |
|
int hardLimit; /* hard limit */ |
|
int lastOp; /* last operation */ |
int lastPos; /* last operation position */ |
int lastLine; /* last operation line */ |
int affectedLen; /* affected len of last operation */ |
int undoBufferLen; /* undo buffer len */ |
char undoBuffer [LEN_MLEDIT_UNDOBUFFER]; |
/* Undo buffer; */ |
PLINEDATA head; /* buffer */ |
|
}MLEDITDATA; |
typedef MLEDITDATA* PMLEDITDATA; |
|
BOOL RegisterMLEditControl (void); |
|
int MLEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam); |
|
#define PIXEL_invalid (-1) |
extern HWND sg_hCaretWnd; |
extern HWND rootwp; |
|
static int GetSysCharHeight (HWND hwnd) |
{ |
#ifndef USE_BIG5 |
HDC hdc; |
int xw, xh, xb; |
|
hdc = GetDC(hwnd); |
SelectObject(hdc, GetStockObject(DEFAULT_FONT)); |
GdSetFont(hdc->font->pfont); |
GdGetTextSize(hdc->font->pfont,"X",1, &xw,&xh,&xb,MWTF_ASCII); |
ReleaseDC(hwnd,hdc); |
|
return xh; |
#else |
return 12; |
#endif |
} |
|
static int GetSysCharWidth (HWND hwnd) |
{ |
#ifndef USE_BIG5 |
HDC hdc; |
int xw, xh, xb; |
|
hdc = GetDC(hwnd); |
SelectObject(hdc, GetStockObject(DEFAULT_FONT)); |
GdSetFont(hdc->font->pfont); |
GdGetTextSize(hdc->font->pfont,"X",1, &xw,&xh,&xb,MWTF_ASCII); |
ReleaseDC(hwnd,hdc); |
|
return xw; |
#else |
return 6; |
#endif |
} |
|
static int GetSysCCharWidth (HWND hwnd) |
{ |
return (2*GetSysCharWidth(hwnd)); |
} |
char* GetWindowCaption (HWND hWnd) |
{ |
return hWnd->szTitle; |
} |
|
DWORD GetWindowAdditionalData (HWND hWnd) |
{ |
return hWnd->userdata; |
} |
|
DWORD SetWindowAdditionalData (HWND hWnd, DWORD newData) |
{ |
DWORD oldOne = 0L; |
|
oldOne = hWnd->userdata; |
hWnd->userdata = newData; |
|
return oldOne; |
} |
|
DWORD GetWindowAdditionalData2 (HWND hWnd) |
{ |
return hWnd->userdata2; |
} |
|
DWORD SetWindowAdditionalData2 (HWND hWnd, DWORD newData) |
{ |
DWORD oldOne = 0L; |
|
oldOne = hWnd->userdata2; |
hWnd->userdata2 = newData; |
|
return oldOne; |
} |
|
DWORD GetWindowStyle (HWND hWnd) |
{ |
return hWnd->style; |
} |
|
BOOL ExcludeWindowStyle (HWND hWnd, DWORD dwStyle) |
{ |
if (hWnd == rootwp/*HWND_DESKTOP*/) |
return FALSE; |
|
hWnd->style &= ~dwStyle; |
return TRUE; |
} |
|
BOOL IncludeWindowStyle (HWND hWnd, DWORD dwStyle) |
{ |
|
if (hWnd == rootwp/*HWND_DESKTOP*/) |
return FALSE; |
|
hWnd->style |= dwStyle; |
return TRUE; |
} |
|
int WINAPI MwRegisterMEditControl(HINSTANCE hInstance) |
{ |
WNDCLASS wc; |
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; |
wc.lpfnWndProc = (WNDPROC)MLEditCtrlProc; |
wc.cbClsExtra = 0; |
wc.cbWndExtra = 0; |
wc.hInstance = hInstance; |
wc.hIcon = NULL; |
wc.hCursor = 0; |
wc.hbrBackground= GetStockObject(WHITE_BRUSH); |
wc.lpszMenuName = NULL; |
wc.lpszClassName= "MEDIT"; |
|
return RegisterClass(&wc); |
} |
|
static inline int edtGetOutWidth (HWND hWnd) |
{ |
PMLEDITDATA pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd); |
RECT rc; |
GetClientRect(hWnd,&rc); |
return rc.right - rc.left |
- pMLEditData->leftMargin |
- pMLEditData->rightMargin; |
} |
|
static int edtGetStartDispPosAtEnd (HWND hWnd, |
PLINEDATA pLineData) |
{ |
int nOutWidth = edtGetOutWidth (hWnd); |
int endPos = pLineData->dataEnd; |
PMLEDITDATA pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd); |
int newStartPos = pMLEditData->dispPos; |
const char* buffer = pLineData->buffer; |
|
if(endPos < newStartPos) |
return 0; |
while (TRUE) |
{ |
if ((endPos - newStartPos) * GetSysCharWidth (hWnd) < nOutWidth) |
break; |
|
/* 1st:gb:a1-f7,big5:a1-f9 */ |
if ((BYTE)buffer [newStartPos] > 0xA0) |
{ |
newStartPos ++; |
if (newStartPos < pLineData->dataEnd) |
{ |
#ifndef USE_BIG5 |
if ((BYTE)buffer [newStartPos] > 0xA0) |
#else /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
if ( ((BYTE)buffer [newStartPos] >= 0x40 && (BYTE)buffer[newStartPos] <= 0x7e) || |
((BYTE)buffer [newStartPos] >= 0xa1 && (BYTE)buffer[newStartPos] <= 0xfe)) |
#endif |
newStartPos ++; |
} |
} |
else |
newStartPos ++; |
} |
return newStartPos; |
} |
|
static int edtGetDispLen (HWND hWnd,PLINEDATA pLineData) |
{ |
int i, n = 0; |
int nOutWidth = edtGetOutWidth (hWnd); |
int nTextWidth = 0; |
PMLEDITDATA pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd); |
const char* buffer = pLineData->buffer; |
|
if(buffer[0]==0||pLineData->dataEnd<pMLEditData->dispPos) |
return 0; |
|
for (i = pMLEditData->dispPos; i < pLineData->dataEnd; i++) |
{ |
/* 1st:gb:a1-f7,big5:a1-f9 */ |
if ((BYTE)buffer [i] > 0xA0) |
{ |
i++; |
if (i < pLineData->dataEnd) |
{ |
#ifndef USE_BIG5 |
if ((BYTE)buffer [i] > 0xA0) /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
#else /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
if ( ((BYTE)buffer [i] >= 0x40 && (BYTE)buffer[i] <= 0x7e) || |
((BYTE)buffer [i] >= 0xa1 && (BYTE)buffer[i] <= 0xfe)) |
#endif |
{ |
nTextWidth += GetSysCCharWidth (hWnd); |
n += 2; |
} |
else |
i--; |
} |
else |
{ |
nTextWidth += GetSysCharWidth (hWnd); |
n++; |
} |
} |
else |
{ |
nTextWidth += GetSysCharWidth (hWnd); |
n++; |
} |
|
if (nTextWidth > nOutWidth) |
break; |
} |
|
return n; |
} |
|
static int edtGetOffset (HWND hwnd,const MLEDITDATA* pMLEditData, PLINEDATA pLineData, int x) |
{ |
int i; |
int newOff = 0; |
int nTextWidth = 0; |
const char* buffer = pLineData->buffer; |
|
if(pLineData->dataEnd<pMLEditData->dispPos) |
return pLineData->dataEnd; |
|
x -= pMLEditData->leftMargin; |
for (i = pMLEditData->dispPos; i < pLineData->dataEnd; i++) { |
if ((nTextWidth + (GetSysCharWidth(hwnd) >> 1)) >= x) |
break; |
|
/* 1st:gb:a1-f7,big5:a1-f9 */ |
if ((BYTE)buffer [i] > 0xA0) |
{ |
i++; |
|
if (nTextWidth + GetSysCCharWidth(hwnd)/2 >= x) |
break; |
|
if (i < pLineData->dataEnd) |
{ |
#ifndef USE_BIG5 |
if ((BYTE)buffer [i] > 0xA0) /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
#else /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
if ( ((BYTE)buffer [i] >= 0x40 && (BYTE)buffer[i] <= 0x7e) || |
((BYTE)buffer [i] >= 0xa1 && (BYTE)buffer[i] <= 0xfe)) |
#endif |
{ |
nTextWidth += GetSysCCharWidth (hwnd); |
newOff += 2; |
} |
else |
i --; |
} |
else |
{ |
nTextWidth += GetSysCharWidth (hwnd); |
newOff ++; |
} |
} |
else |
{ |
nTextWidth += GetSysCharWidth (hwnd); |
newOff ++; |
} |
} |
return newOff; |
} |
|
static int edtGetLineNO (HWND hwnd,const MLEDITDATA* pMLEditData, int x) |
{ |
int nline = 0; |
if(x>=0) |
{ |
nline = x / GetSysCharHeight(hwnd); |
if (nline <= pMLEditData->linesDisp) |
return nline; |
} |
return -1; |
} |
|
static BOOL edtIsACCharAtPosition (const char* string, int len, int pos) |
{ |
if (pos > (len - 2)) |
return FALSE; |
|
/* 1st:gb:a1-f7,big5:a1-f9 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
#ifndef USE_BIG5 |
if ((BYTE)string [pos] > 0xA0 && (BYTE)string [pos + 1] > 0xA0) |
return TRUE; |
#else |
if ((BYTE)string [pos] > 0xA0) |
{ |
if ( ((BYTE)string [pos + 1] >= 0x40 && (BYTE)string [pos + 1] <= 0x7e) || |
((BYTE)string [pos + 1] >= 0xa1 && (BYTE)string [pos + 1] <= 0xfe)) { |
/*fprintf(stderr,"true\n"); |
fflush(stderr);*/ |
return TRUE; |
} |
} |
#endif |
|
return FALSE; |
} |
|
static void str2attr(const char* str,int len) |
{ |
int i=0; |
do |
{ |
if (edtIsACCharAtPosition(str,len,i)) |
{ |
attr[i]=ATTCHL; |
attr[i+1]=ATTCHR; |
i+=2; |
} |
else |
{ |
attr[i]=ATTENG; |
i++; |
} |
}while(i<len); |
} |
|
static BOOL edtIsACCharBeforePosition (const char* string,int len, int pos) |
{ |
if (pos < 2) |
return FALSE; |
|
/* 1st:gb:a1-f7,big5:a1-f9 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
#ifndef USE_BIG5 |
/* FIXME #ifdef GB2312?*/ |
if ((BYTE)string [pos - 2] > 0xA0 && (BYTE)string [pos - 1] > 0xA0) |
return TRUE; |
#else |
#if 0 |
if ((BYTE)string [pos - 2] > 0xA0) |
{ |
if ( ((BYTE)string [pos - 1] >= 0x40 && (BYTE)string[pos - 1] <= 0x7e) || |
((BYTE)string [pos - 1] >= 0xa1 && (BYTE)string[pos - 1] <= 0xfe)) |
return TRUE; |
} |
#else |
str2attr(string,len); |
if (attr[pos-1]==ATTENG) return FALSE; |
else return TRUE; |
#endif |
#endif |
|
return FALSE; |
} |
|
|
static BOOL edtIsACCharFromBegin(const char* string,int len,int pos) |
{ |
int i; |
if(pos == 0) |
return TRUE; |
if(len == 0) |
return FALSE; |
for(i=0;i<len;) |
{ |
if( edtIsACCharAtPosition(string,len,i) ) |
i += 2; |
else |
i++; |
if(i==pos) |
return TRUE; |
} |
return FALSE; |
} |
|
int GetRETURNPos(char *str) |
{ |
int i; |
for(i=0;i<strlen(str);i++) |
{ |
if(str[i]==10) |
return i; |
} |
return -1; |
} |
|
void MLEditInitBuffer (PMLEDITDATA pMLEditData,char *spcaption) |
{ |
char *caption=spcaption; |
int off1; |
int lineNO=0; |
PLINEDATA pLineData; |
if (!(pMLEditData->head = malloc (sizeof (LINEDATA)))) { |
fprintf (stderr, "EDITLINE: malloc error!\n"); |
return ; |
} |
pMLEditData->head->previous = NULL; |
pLineData=pMLEditData->head; |
while ( (off1 = GetRETURNPos(caption)) != -1) |
{ |
off1 = min(off1, LEN_MLEDIT_BUFFER); |
memcpy(pLineData->buffer,caption,off1); |
pLineData->buffer[off1] = '\0'; |
caption+=min(off1,LEN_MLEDIT_BUFFER)+1; |
pLineData->lineNO = lineNO; |
pMLEditData->dispPos = 0; |
pLineData->dataEnd = strlen(pLineData->buffer); |
pLineData->next = malloc (sizeof (LINEDATA)); |
pLineData->next->previous = pLineData; |
pLineData = pLineData->next; |
lineNO++; |
} |
off1 = min(strlen(caption),LEN_MLEDIT_BUFFER); |
memcpy(pLineData->buffer,caption,off1); |
pLineData->buffer[off1] = '\0'; |
pLineData->lineNO = lineNO++; |
pMLEditData->dispPos = 0; |
pLineData->dataEnd = strlen(pLineData->buffer); |
pLineData->next = NULL; |
pMLEditData->lines = lineNO ; |
} |
|
PLINEDATA GetLineData(PMLEDITDATA pMLEditData,int lineNO) |
{ |
PLINEDATA pLineData=pMLEditData->head; |
while(pLineData) |
{ |
if(pLineData->lineNO==lineNO) |
return pLineData; |
pLineData = pLineData->next; |
} |
return NULL; |
} |
|
int MLEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam) |
{ |
DWORD dwStyle; |
DWORD dw; |
HDC hdc; |
PLINEDATA pLineData; |
RECT clientRect; |
PMLEDITDATA pMLEditData; |
dwStyle = GetWindowStyle(hWnd); |
|
switch (message) |
{ |
case WM_CREATE: |
{ |
if (!(pMLEditData = malloc (sizeof (MLEDITDATA)))) { |
fprintf (stderr, "EDIT: malloc error!\n"); |
return -1; |
} |
|
pMLEditData->totalLen = LEN_MLEDIT_BUFFER; |
pMLEditData->editPos = 0; |
pMLEditData->editLine = 0; |
pMLEditData->caretPos = 0; |
|
MLEditInitBuffer(pMLEditData,GetWindowCaption(hWnd)); |
|
GetClientRect(hWnd,&clientRect); |
pMLEditData->MaxlinesDisp = (clientRect.bottom-clientRect.top)/GetSysCharHeight(hWnd); |
pMLEditData->linesDisp = min(pMLEditData->MaxlinesDisp,pMLEditData->lines); |
pMLEditData->StartlineDisp = 0; |
pMLEditData->EndlineDisp = pMLEditData->StartlineDisp + pMLEditData->linesDisp - 1; |
|
pMLEditData->selStartPos = 0; |
pMLEditData->selEndPos = 0; |
pMLEditData->passwdChar = '*'; |
pMLEditData->leftMargin = MARGIN_MEDIT_LEFT; |
pMLEditData->topMargin = MARGIN_MEDIT_TOP; |
pMLEditData->rightMargin = MARGIN_MEDIT_RIGHT; |
pMLEditData->bottomMargin = MARGIN_MEDIT_BOTTOM; |
|
pMLEditData->hardLimit = -1; |
|
/* undo information */ |
pMLEditData->lastOp = MEDIT_OP_NONE; |
pMLEditData->lastPos = 0; |
pMLEditData->affectedLen = 0; |
pMLEditData->undoBufferLen = LEN_MLEDIT_UNDOBUFFER; |
pMLEditData->undoBuffer [0] = '\0'; |
SetWindowAdditionalData2(hWnd,(DWORD)pMLEditData); |
SetWindowAdditionalData(hWnd,(DWORD)0); |
break; |
} |
case WM_DESTROY: |
{ |
PLINEDATA temp; |
pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd); |
DestroyCaret (); |
pLineData = pMLEditData->head; |
while(pLineData) |
{ |
/*printf("delete lineNO = %d,buffer=%s\n",pLineData->lineNO,pLineData->buffer);*/ |
temp = pLineData->next; |
free(pLineData); |
pLineData = temp; |
} |
free(pMLEditData); |
} |
break; |
|
case WM_SETFONT: |
break; |
|
case WM_GETFONT: |
break; |
|
#if 0 /* fix: no WM_SETCURSOR */ |
case WM_SETCURSOR: |
if (dwStyle & WS_DISABLED) { |
SetCursor (GetSystemCursor (IDC_ARROW)); |
return 0; |
} |
break; |
|
case WM_SIZECHANGED: |
{ |
} |
return 0; |
#endif |
case WM_KILLFOCUS: |
{ |
dw= GetWindowAdditionalData(hWnd); |
dw&= ~EST_FOCUSED; |
SetWindowAdditionalData(hWnd,dw); |
|
HideCaret (hWnd); |
DestroyCaret (); |
|
SendMessage (GetParent (hWnd), |
WM_COMMAND, |
(WPARAM) MAKELONG (GetDlgCtrlID(hWnd), EN_KILLFOCUS), |
(LPARAM)hWnd); |
} |
break; |
|
case WM_SETFOCUS: |
{ |
dw= GetWindowAdditionalData(hWnd); |
if (dw & EST_FOCUSED) |
return 0; |
|
dw |= EST_FOCUSED; |
SetWindowAdditionalData(hWnd,dw); |
|
pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd); |
|
/* only implemented for ES_LEFT align format. */ |
|
CreateCaret (hWnd, NULL, 1, /*GetSysCharWidth(hWnd)+1,*/ |
hWnd->clirect.bottom-hWnd->clirect.top-2); |
SetCaretPos (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin, pMLEditData->topMargin); |
ShowCaret(hWnd); |
|
SendMessage (GetParent (hWnd), |
WM_COMMAND, |
(WPARAM) MAKELONG (GetDlgCtrlID(hWnd), EN_SETFOCUS), |
(LPARAM) hWnd); |
} |
break; |
|
case WM_ENABLE: |
if ( (!(dwStyle & WS_DISABLED) && !wParam) |
|| ((dwStyle & WS_DISABLED) && wParam) ) { |
if (wParam) |
ExcludeWindowStyle(hWnd,WS_DISABLED); |
else |
IncludeWindowStyle(hWnd,WS_DISABLED); |
|
InvalidateRect (hWnd, NULL, FALSE); |
} |
return 0; |
|
case WM_NCPAINT: |
{ |
RECT rc; |
#if 0 |
if (wParam) |
hdc = (HDC)wParam; |
else |
hdc = GetDC (hWnd); |
#if 0 /* fix: no ClipRectIntersect() */ |
if (lParam) |
ClipRectIntersect (hdc, (RECT*)lParam); |
#endif |
#else |
hdc = wParam? (HDC)wParam: GetWindowDC (hWnd); |
GetWindowRect(hWnd, &rc); |
#endif |
if (dwStyle & WS_BORDER) |
{ |
#if 0 |
RECT rc; |
GetWindowRect(hWnd,&rc); |
Draw3DDownFrame (hdc, 0, 0, |
rc.right - rc.left - 1, |
rc.bottom - rc.top - 1, |
PIXEL_invalid); |
#else |
Draw3dInset(hdc, rc.left, rc.top, |
rc.right-rc.left, rc.bottom-rc.top); |
#endif |
} |
if (!wParam) { |
ReleaseDC(hWnd,hdc); |
} |
} |
return 0; |
|
case WM_PAINT: |
{ |
int dispLen,i; |
char* dispBuffer; |
RECT rect,rc; |
PAINTSTRUCT ps; |
HGDIOBJ oldfont=NULL; |
|
hdc = BeginPaint (hWnd,&ps); |
GetClientRect (hWnd, &rect); |
|
if (dwStyle & WS_DISABLED) |
{ |
rc.left=0; rc.top=0; rc.bottom=rect.bottom; rc.right=rect.right; |
FillRect(hdc,&rc,GetStockObject(LTGRAY_BRUSH)); |
SetBkColor (hdc, LTGRAY/*PIXEL_lightgray*/); |
} |
else { |
rc.left=0; rc.top=0; rc.bottom=rect.bottom; rc.right=rect.right; |
FillRect(hdc,&rc,GetStockObject(WHITE_BRUSH)); |
SetBkColor (hdc, WHITE/*PIXEL_lightwhite*/); |
} |
|
SetTextColor (hdc, BLACK/*PIXEL_black*/); |
|
pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd); |
for(i = pMLEditData->StartlineDisp; i <= pMLEditData->EndlineDisp; i++) |
{ |
pLineData= GetLineData(pMLEditData,i); |
dispLen = edtGetDispLen (hWnd,pLineData); |
if (dispLen == 0 && pMLEditData->EndlineDisp >= pMLEditData->lines) { |
continue; |
} |
|
#ifdef _DEBUG |
if (pMLEditData->dispPos > pLineData->dataEnd) |
fprintf (stderr, "ASSERT failure: %s.\n", "Edit Paint"); |
#endif |
|
dispBuffer = alloca (LEN_MLEDIT_BUFFER+1); |
|
if (dwStyle & ES_PASSWORD) |
memset (dispBuffer, '*', pLineData->dataEnd); |
memcpy (dispBuffer, |
pLineData->buffer, /* +pMLEditData->dispPos, */ |
pLineData->dataEnd); /* - pMLEditData->dispPos); */ |
dispBuffer[pLineData->dataEnd] = '\0'; |
|
/* only implemented ES_LEFT align format for single line edit. */ |
rect.left = pMLEditData->leftMargin; |
rect.top = pMLEditData->topMargin ; |
rect.right = pMLEditData->rightMargin; |
rect.bottom = pMLEditData->bottomMargin; |
#if 0 |
printf("lineNO=%d,lines=%d,editLine=%d\n",pLineData->lineNO,pMLEditData->lines, |
pMLEditData->editLine); |
printf("--dispBuffer=%s--\n",dispBuffer); |
ClipRectIntersect (hdc, &rect); /* fix: no ClipRectIntersect() */ |
#endif |
|
#ifdef USE_BIG5 |
oldfont=SelectObject(hdc,CreateFont(12, |
0,0,0,0,0,0,0,0,0,0,0, |
FF_DONTCARE|DEFAULT_PITCH, |
"HZXFONT")); |
#endif |
TextOut (hdc, |
pMLEditData->leftMargin - pMLEditData->dispPos * GetSysCharWidth(hWnd) , |
GetSysCharHeight(hWnd)*(pLineData->lineNO - pMLEditData->StartlineDisp) |
+ pMLEditData->topMargin, |
dispBuffer,-1); |
} |
#ifdef USE_BIG5 |
DeleteObject(SelectObject(hdc,oldfont)); |
#endif |
EndPaint (hWnd, &ps); |
} |
break; |
|
case WM_KEYDOWN: |
{ |
BOOL bChange = FALSE; |
int i; |
int deleted; |
PLINEDATA temp = NULL; |
char * tempP = NULL; |
|
pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd); |
|
switch (LOWORD (wParam)) |
{ |
|
case VK_RETURN: /* SCANCODE_ENTER: */ |
{ |
pLineData = GetLineData(pMLEditData,pMLEditData->editLine); |
if (pMLEditData->editPos < pLineData->dataEnd) |
tempP = pLineData->buffer + pMLEditData->editPos; |
temp = pLineData->next; |
pLineData->next = malloc( sizeof(LINEDATA) ); |
pLineData->next->previous = pLineData; |
pLineData->next->next = temp; |
if(temp) |
{ |
temp->previous = pLineData->next; |
} |
temp = pLineData->next; |
temp->lineNO = pMLEditData->editLine + 1; |
if(tempP) |
{ |
memcpy(temp->buffer,tempP,strlen(tempP)); |
temp->dataEnd = strlen(tempP); |
} |
else |
temp->dataEnd = 0; |
temp->buffer[temp->dataEnd] = '\0'; |
pLineData->dataEnd = pMLEditData->editPos; |
pLineData->buffer[pLineData->dataEnd]='\0'; |
temp = temp->next; |
while (temp) |
{ |
temp->lineNO++; |
temp = temp->next; |
} |
pMLEditData->editPos = 0; |
pMLEditData->caretPos= 0; |
pMLEditData->dispPos = 0; |
if(pMLEditData->linesDisp < pMLEditData->MaxlinesDisp) |
{ |
pMLEditData->EndlineDisp++; |
pMLEditData->linesDisp++; |
} |
else if(pMLEditData->editLine == pMLEditData->EndlineDisp) |
{ |
pMLEditData->StartlineDisp++; |
pMLEditData->EndlineDisp++; |
} |
pMLEditData->editLine++; |
pMLEditData->lines++; |
SetCaretPos (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin, |
(pMLEditData->editLine - pMLEditData->StartlineDisp) * GetSysCharHeight(hWnd) |
+pMLEditData->topMargin); |
InvalidateRect (hWnd, NULL, FALSE); |
return 0; |
} |
case VK_HOME: /* SCANCODE_HOME: */ |
{ |
PLINEDATA temp; |
if (pMLEditData->editPos == 0) |
return 0; |
|
pMLEditData->editPos = 0; |
pMLEditData->caretPos = 0; |
|
SetCaretPos (pMLEditData->leftMargin, |
(pMLEditData->editLine-pMLEditData->StartlineDisp) * GetSysCharHeight(hWnd) |
+pMLEditData->topMargin); |
temp = GetLineData(pMLEditData,pMLEditData->editLine); |
if (pMLEditData->dispPos != 0) |
{ |
pMLEditData->dispPos = 0; |
InvalidateRect (hWnd, NULL, FALSE); |
} |
return 0; |
} |
case VK_END: /* SCANCODE_END: */ |
{ |
int newStartPos; |
pLineData = GetLineData(pMLEditData,pMLEditData->editLine); |
if (pMLEditData->editPos == pLineData->dataEnd) |
return 0; |
newStartPos = edtGetStartDispPosAtEnd (hWnd, pLineData); |
|
pMLEditData->editPos = pLineData->dataEnd; |
pMLEditData->caretPos = pMLEditData->editPos - newStartPos; |
|
SetCaretPos (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin, |
(pMLEditData->editLine-pMLEditData->StartlineDisp) * GetSysCharHeight(hWnd) |
+ pMLEditData->topMargin); |
|
if (pMLEditData->dispPos != newStartPos) |
InvalidateRect (hWnd, NULL, FALSE); |
pMLEditData->dispPos = newStartPos; |
} |
return 0; |
|
case VK_LEFT: /* SCANCODE_CURSORBLOCKLEFT: */ |
{ |
BOOL bScroll = FALSE; |
int scrollStep,newStartPos; |
PLINEDATA temp; |
pLineData = GetLineData(pMLEditData,pMLEditData->editLine); |
if (pMLEditData->editPos == 0 ) |
{ |
temp = pLineData->previous; |
if(temp && pMLEditData->editLine > pMLEditData->StartlineDisp) |
{ |
pMLEditData->editLine --; |
pMLEditData->editPos = temp->dataEnd; |
newStartPos = edtGetStartDispPosAtEnd (hWnd, temp); |
pMLEditData->caretPos = pMLEditData->editPos - newStartPos; |
if (pMLEditData->dispPos != newStartPos) |
{ |
pMLEditData->dispPos = newStartPos; |
bScroll = TRUE; |
} |
} |
else |
return 0; |
} |
else |
{ if (edtIsACCharBeforePosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->editPos)) { |
scrollStep = 2; |
pMLEditData->editPos -= 2; |
} |
else { |
scrollStep = 1; |
pMLEditData->editPos --; |
} |
|
pMLEditData->caretPos -= scrollStep; |
if (pMLEditData->caretPos == 0 |
&& pMLEditData->editPos != 0) { |
|
bScroll = TRUE; |
|
if (edtIsACCharBeforePosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->editPos)) { |
pMLEditData->dispPos -= 2; |
pMLEditData->caretPos = 2; |
} |
else { |
pMLEditData->dispPos--; |
pMLEditData->caretPos = 1; |
} |
} |
else if (pMLEditData->caretPos < 0) { |
pMLEditData->dispPos = 0; |
pMLEditData->caretPos = 0; |
} |
} |
SetCaretPos (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin, |
(pMLEditData->editLine - pMLEditData->StartlineDisp) * GetSysCharHeight(hWnd) |
+ pMLEditData->topMargin); |
|
if (bScroll) |
InvalidateRect (hWnd, NULL, FALSE); |
} |
return 0; |
|
case VK_RIGHT: /* SCANCODE_CURSORBLOCKRIGHT: */ |
{ |
BOOL bScroll = FALSE; |
int scrollStep, moveStep; |
PLINEDATA temp; |
|
pLineData = GetLineData(pMLEditData,pMLEditData->editLine); |
if (pMLEditData->editPos == pLineData->dataEnd) |
{ |
temp = pLineData->next; |
if(temp) |
{ |
pMLEditData->editLine++; |
pMLEditData->editPos = 0; |
pMLEditData->caretPos = 0; |
if(pMLEditData->dispPos !=0) |
{ |
pMLEditData->dispPos = 0; |
bScroll = TRUE; |
} |
} |
else |
return 0; |
} |
else |
{ |
if (edtIsACCharAtPosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->dispPos)) { |
if (edtIsACCharAtPosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->editPos)) { |
scrollStep = 2; |
moveStep = 2; |
pMLEditData->editPos += 2; |
} |
else { |
scrollStep = 2; |
moveStep = 1; |
pMLEditData->editPos ++; |
} |
} |
else { |
if (edtIsACCharAtPosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->editPos)) { |
|
if (edtIsACCharAtPosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->dispPos + 1)) |
scrollStep = 3; |
else |
scrollStep = 2; |
|
moveStep = 2; |
pMLEditData->editPos += 2; |
} |
else { |
scrollStep = 1; |
moveStep = 1; |
pMLEditData->editPos ++; |
} |
} |
|
pMLEditData->caretPos += moveStep; |
if (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
> edtGetOutWidth (hWnd)) { |
bScroll = TRUE; |
pMLEditData->dispPos += scrollStep; |
pMLEditData->caretPos = |
pMLEditData->editPos - pMLEditData->dispPos; |
} |
} |
SetCaretPos (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin, |
(pMLEditData->editLine - pMLEditData->StartlineDisp) * GetSysCharHeight (hWnd) |
+ pMLEditData->topMargin); |
|
if (bScroll) |
InvalidateRect (hWnd, NULL, FALSE); |
} |
return 0; |
|
case VK_UP: /* SCANCODE_CURSORBLOCKUP: */ |
{ |
BOOL bScroll = FALSE; |
int newStartPos; |
PLINEDATA temp; |
pLineData = GetLineData(pMLEditData,pMLEditData->editLine); |
temp = pLineData->previous; |
if(pMLEditData->editLine == 0) |
return 0; |
else if (pMLEditData->editLine == pMLEditData->StartlineDisp) |
{ |
bScroll = TRUE; |
pMLEditData->StartlineDisp--; |
pMLEditData->EndlineDisp--; |
} |
pMLEditData->editLine--; |
|
if( pMLEditData->editPos >= temp->dataEnd ) |
{ |
pMLEditData->editPos = temp->dataEnd; |
pMLEditData->dispPos = 0; |
newStartPos = edtGetStartDispPosAtEnd (hWnd, temp); |
pMLEditData->dispPos = newStartPos; |
pMLEditData->caretPos = pMLEditData->editPos - newStartPos; |
bScroll = TRUE; |
} |
else |
{ |
newStartPos = edtGetOffset(hWnd, pMLEditData,temp, |
pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin); |
if(!edtIsACCharFromBegin(temp->buffer,temp->dataEnd, |
pMLEditData->dispPos)) |
{ |
bScroll = TRUE; |
pMLEditData->dispPos--; |
newStartPos = edtGetOffset(hWnd, pMLEditData,temp, |
pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin+GetSysCharWidth(hWnd)/2); |
} |
pMLEditData->editPos = newStartPos + pMLEditData->dispPos; |
pMLEditData->caretPos = newStartPos; |
} |
SetCaretPos (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin, |
(pMLEditData->editLine - pMLEditData->StartlineDisp) * GetSysCharHeight(hWnd) |
+ pMLEditData->topMargin); |
if(bScroll) |
InvalidateRect(hWnd,NULL,FALSE); |
} |
break; |
case VK_DOWN: /* SCANCODE_CURSORBLOCKDOWN: */ |
{ |
BOOL bScroll = FALSE; |
int newStartPos; |
PLINEDATA temp; |
pLineData = GetLineData(pMLEditData,pMLEditData->editLine); |
temp = pLineData->next; |
if(pMLEditData->editLine == pMLEditData->lines-1) |
return 0; |
else if (pMLEditData->editLine == pMLEditData->EndlineDisp) |
{ |
bScroll = TRUE; |
pMLEditData->StartlineDisp++; |
pMLEditData->EndlineDisp++; |
} |
pMLEditData->editLine++; |
|
if( pMLEditData->editPos >= temp->dataEnd ) |
{ |
pMLEditData->editPos = temp->dataEnd; |
pMLEditData->dispPos = 0; |
newStartPos = edtGetStartDispPosAtEnd (hWnd, temp); |
pMLEditData->dispPos = newStartPos; |
pMLEditData->caretPos = pMLEditData->editPos - newStartPos; |
bScroll = TRUE; |
} |
else |
{ |
newStartPos = edtGetOffset(hWnd, pMLEditData,temp, |
pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin); |
if(!edtIsACCharFromBegin(temp->buffer,temp->dataEnd, |
pMLEditData->dispPos)) |
{ |
bScroll = TRUE; |
pMLEditData->dispPos--; |
newStartPos = edtGetOffset(hWnd, pMLEditData,temp, |
pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin+GetSysCharWidth(hWnd)/2); |
} |
pMLEditData->editPos = newStartPos + pMLEditData->dispPos; |
pMLEditData->caretPos = newStartPos; |
} |
SetCaretPos (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin, |
(pMLEditData->editLine - pMLEditData->StartlineDisp) * GetSysCharHeight(hWnd) |
+ pMLEditData->topMargin); |
if(bScroll) |
InvalidateRect(hWnd,NULL,FALSE); |
|
} |
break; |
case VK_INSERT: /* SCANCODE_INSERT: */ |
dw = GetWindowAdditionalData(hWnd); |
dw ^= EST_REPLACE; |
SetWindowAdditionalData(hWnd,dw); |
break; |
|
case VK_DELETE: /* SCANCODE_REMOVE: */ |
{ |
PLINEDATA temp; |
int leftLen; |
pLineData = GetLineData(pMLEditData,pMLEditData->editLine); |
if ((GetWindowAdditionalData(hWnd) & EST_READONLY) ){ |
#if 0 /* fix: no ping() */ |
ping (); |
#endif |
return 0; |
} |
temp = pLineData->next; |
if (pLineData->dataEnd == pMLEditData->editPos && temp) |
{ |
if(pLineData->dataEnd + temp->dataEnd <= LEN_MLEDIT_BUFFER) |
{ |
memcpy(pLineData->buffer+pLineData->dataEnd,temp->buffer,temp->dataEnd); |
pLineData->dataEnd += temp->dataEnd; |
pLineData->buffer[pLineData->dataEnd] = '\0'; |
if(temp->next) |
{ |
pLineData->next = temp->next; |
temp->next->previous = pLineData; |
} |
else |
pLineData->next = NULL; |
free(temp); |
temp = pLineData->next; |
while (temp) |
{ |
temp->lineNO--; |
temp = temp->next; |
} |
if(pMLEditData->lines <= pMLEditData->MaxlinesDisp) |
{ |
pMLEditData->EndlineDisp--; |
pMLEditData->linesDisp--; |
} |
if(pMLEditData->EndlineDisp >= pMLEditData->lines-1) |
{ |
pMLEditData->EndlineDisp--; |
if(pMLEditData->StartlineDisp !=0) |
pMLEditData->StartlineDisp--; |
else |
pMLEditData->linesDisp--; |
} |
pMLEditData->lines--; |
} |
else if (temp->dataEnd > 0) |
{ |
leftLen = LEN_MLEDIT_BUFFER - pLineData->dataEnd; |
memcpy(pLineData->buffer+pLineData->dataEnd,temp->buffer,leftLen); |
pLineData->dataEnd +=leftLen; |
pLineData->buffer[pLineData->dataEnd] = '\0'; |
memcpy(temp->buffer,temp->buffer+leftLen,temp->dataEnd-leftLen); |
temp->dataEnd -=leftLen; |
temp->buffer[temp->dataEnd] = '\0'; |
} |
} |
else if (pMLEditData->editPos != pLineData->dataEnd) |
{ |
if (edtIsACCharAtPosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->editPos)) |
deleted = 2; |
else |
deleted = 1; |
|
for (i = pMLEditData->editPos; |
i < pLineData->dataEnd - deleted; |
i++) |
pLineData->buffer [i] |
= pLineData->buffer [i + deleted]; |
|
pLineData->dataEnd -= deleted; |
pLineData->buffer[pLineData->dataEnd] = '\0'; |
} |
bChange = TRUE; |
InvalidateRect (hWnd, NULL,FALSE); |
} |
break; |
|
case VK_BACK: /* SCANCODE_BACKSPACE: */ |
{ |
PLINEDATA temp; |
int leftLen,tempEnd; |
if ((GetWindowAdditionalData(hWnd) & EST_READONLY) ){ |
#if 0 /* fix: no Ping() */ |
Ping (); |
#endif |
return 0; |
} |
pLineData = GetLineData(pMLEditData,pMLEditData->editLine); |
temp = pLineData->previous; |
if (pMLEditData->editPos == 0 && temp) |
{ |
tempEnd = temp->dataEnd; |
if(pLineData->dataEnd + temp->dataEnd <= LEN_MLEDIT_BUFFER) |
{ |
memcpy(temp->buffer+temp->dataEnd,pLineData->buffer,pLineData->dataEnd); |
temp->dataEnd +=pLineData->dataEnd; |
temp->buffer[temp->dataEnd] = '\0'; |
if(pLineData->next) |
{ |
temp->next = pLineData->next; |
pLineData->next->previous = temp; |
} |
else |
temp->next = NULL; |
free(pLineData); |
pLineData = temp; |
temp = temp->next; |
while(temp) |
{ |
temp->lineNO--; |
temp = temp->next; |
} |
if(pMLEditData->StartlineDisp == pMLEditData->editLine |
&& pMLEditData->StartlineDisp != 0) |
{ |
pMLEditData->StartlineDisp--; |
if(pMLEditData->EndlineDisp == pMLEditData->lines) |
pMLEditData->EndlineDisp--; |
} |
if(pMLEditData->lines <= pMLEditData->MaxlinesDisp) |
{ |
pMLEditData->linesDisp--; |
pMLEditData->EndlineDisp--; |
} |
pMLEditData->lines--; |
} |
else if (pLineData->dataEnd > 0) |
{ |
leftLen = LEN_MLEDIT_BUFFER - temp->dataEnd; |
memcpy(temp->buffer+temp->dataEnd,pLineData->buffer,leftLen); |
temp->dataEnd +=leftLen; |
temp->buffer[temp->dataEnd] = '\0'; |
memcpy(pLineData->buffer,pLineData->buffer+leftLen,pLineData->dataEnd-leftLen); |
pLineData->dataEnd -=leftLen; |
pLineData->buffer[pLineData->dataEnd] = '\0'; |
} |
pMLEditData->editLine--; |
pMLEditData->editPos = tempEnd; |
pMLEditData->dispPos = tempEnd; |
|
if (pMLEditData->caretPos == 0 |
&& pMLEditData->editPos != 0) { |
if (edtIsACCharBeforePosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->editPos)) { |
pMLEditData->dispPos -= 2; |
pMLEditData->caretPos = 2; |
} |
else { |
pMLEditData->dispPos--; |
pMLEditData->caretPos = 1; |
} |
} |
else if (pMLEditData->caretPos < 0) { |
pMLEditData->dispPos = 0; |
pMLEditData->caretPos = 0; |
} |
} |
else if (pMLEditData->editPos != 0 ) |
{ |
if (edtIsACCharBeforePosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->editPos)) |
deleted = 2; |
else |
deleted = 1; |
|
for (i = pMLEditData->editPos; |
i < pLineData->dataEnd; |
i++) |
pLineData->buffer [i - deleted] |
= pLineData->buffer [i]; |
|
pLineData->dataEnd -= deleted; |
pMLEditData->editPos -= deleted; |
pMLEditData->caretPos -= deleted; |
if (pMLEditData->caretPos == 0 |
&& pMLEditData->editPos != 0) { |
if (edtIsACCharBeforePosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->editPos)) { |
pMLEditData->dispPos -= 2; |
pMLEditData->caretPos = 2; |
} |
else { |
pMLEditData->dispPos --; |
pMLEditData->caretPos = 1; |
} |
|
} |
} |
bChange = TRUE; |
SetCaretPos (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin, |
(pMLEditData->editLine - pMLEditData->StartlineDisp) * GetSysCharHeight(hWnd) |
+ pMLEditData->topMargin); |
InvalidateRect (hWnd, NULL, FALSE); |
} |
break; |
|
default: |
break; |
} |
|
if (bChange) |
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (GetDlgCtrlID(hWnd), EN_CHANGE), |
(LPARAM) hWnd); |
return 0; |
} |
|
case WM_CHAR: |
{ |
char charBuffer [2]; |
int i, chars, scrollStep, inserting; |
UINT format; |
|
pMLEditData = (PMLEDITDATA)GetWindowAdditionalData2(hWnd); |
|
pLineData = GetLineData(pMLEditData,pMLEditData->editLine); |
|
if (dwStyle & ES_READONLY) { |
#if 0 /* fix: no Ping() */ |
Ping (); |
#endif |
return 0; |
} |
if (HIBYTE (wParam)) { |
charBuffer [0] = LOBYTE (wParam); |
charBuffer [1] = HIBYTE (wParam); |
chars = 2; |
} |
else { |
charBuffer [0] = LOBYTE (wParam); |
chars = 1; |
} |
|
if (chars == 1) { |
switch (charBuffer [0]) |
{ |
case 0x00: /* NULL */ |
case 0x07: /* BEL */ |
case 0x08: /* BS */ |
case 0x09: /* HT */ |
case 0x0A: /* LF */ |
case 0x0B: /* VT */ |
case 0x0C: /* FF */ |
case 0x0D: /* CR */ |
case 0x1B: /* Escape */ |
return 0; |
} |
} |
if (GetWindowAdditionalData(hWnd) & EST_REPLACE) { |
if (pLineData->dataEnd == pMLEditData->editPos) |
inserting = chars; |
else if (edtIsACCharAtPosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->editPos)) { |
if (chars == 2) |
inserting = 0; |
else |
inserting = -1; |
} |
else { |
if (chars == 2) |
inserting = 1; |
else |
inserting = 0; |
} |
} |
else |
inserting = chars; |
|
/* check space */ |
if (pLineData->dataEnd + inserting > pMLEditData->totalLen) { |
#if 0 /* fix no ping */ |
Ping (); |
#endif |
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (GetDlgCtrlID(hWnd), EN_MAXTEXT), |
(LPARAM) hWnd); |
return 0; |
} |
else if ((pMLEditData->hardLimit >= 0) |
&& ((pLineData->dataEnd + inserting) |
> pMLEditData->hardLimit)) { |
#if 0 /* fix no ping */ |
Ping (); |
#endif |
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (GetDlgCtrlID(hWnd), EN_MAXTEXT), |
(LPARAM) hWnd); |
return 0; |
} |
if (inserting == -1) { |
for (i = pMLEditData->editPos; i < pLineData->dataEnd-1; i++) |
pLineData->buffer [i] = pLineData->buffer [i + 1]; |
} |
else if (inserting > 0) { |
for (i = pLineData->dataEnd + inserting - 1; |
i > pMLEditData->editPos + inserting - 1; |
i--) |
pLineData->buffer [i] |
= pLineData->buffer [i - inserting]; |
} |
for (i = 0; i < chars; i++) |
pLineData->buffer [pMLEditData->editPos + i] |
= charBuffer [i]; |
|
pMLEditData->editPos += chars; |
pMLEditData->caretPos += chars; |
pLineData->dataEnd += inserting; |
pLineData->buffer[pLineData->dataEnd] = '\0'; |
if (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
> edtGetOutWidth (hWnd)) |
{ |
if (edtIsACCharAtPosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->dispPos)) |
scrollStep = 2; |
else { |
if (chars == 2) { |
if (edtIsACCharAtPosition (pLineData->buffer, |
pLineData->dataEnd, |
pMLEditData->dispPos + 1)) |
scrollStep = 3; |
else |
scrollStep = 2; |
} |
else |
scrollStep = 1; |
} |
|
pMLEditData->dispPos += scrollStep; |
|
pMLEditData->caretPos = |
pMLEditData->editPos - pMLEditData->dispPos; |
|
} |
SetCaretPos (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin, |
(pMLEditData->editLine - pMLEditData->StartlineDisp) * GetSysCharHeight(hWnd) |
+ pMLEditData->topMargin); |
InvalidateRect (hWnd, NULL,FALSE); |
format = DT_NOPREFIX; |
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (GetDlgCtrlID(hWnd), EN_CHANGE), |
(LPARAM) hWnd); |
} |
return 0; |
|
case WM_GETTEXTLENGTH: |
{ |
PLINEDATA temp; |
int lineNO = (int)wParam; |
pMLEditData = (PMLEDITDATA)GetWindowAdditionalData2(hWnd); |
temp = pMLEditData->head; |
while(temp) |
{ |
if (temp->lineNO == lineNO) |
return temp->dataEnd; |
temp = temp->next; |
} |
return -1; |
} |
case WM_GETTEXT: |
{ |
PLINEDATA temp; |
int len,total = 0,lineNO; |
char * buffer = (char*)lParam; |
pMLEditData = (PMLEDITDATA)GetWindowAdditionalData2(hWnd); |
len = (int)wParam; |
lineNO = (int)wParam; |
temp = pMLEditData->head; |
while (temp && total + temp->dataEnd < len) |
{ |
memcpy(buffer+total,temp->buffer,temp->dataEnd); |
total += temp->dataEnd; |
temp = temp->next; |
} |
|
} |
return 0; |
/* can i add it to message define ? */ |
#if 0 |
case WM_GETLINETEXT: |
{ |
PLINEDATA temp; |
char* buffer = (char*)lParam; |
int lineNO,len; |
|
pMLEditData = (PMLEDITDATA)GetWindowAdditionalData2(hWnd); |
lineNO = (int)wParam; |
temp = GetLineData(pMLEditData,lineNO); |
if(temp) |
{ |
len = min ((int)wParam, temp->dataEnd); |
memcpy (buffer, temp->buffer,len); |
buffer [len] = '\0'; |
return 0; |
} |
return -1; |
} |
break; |
case WM_SETTEXT: |
{ |
MLEditInitBuffer(pMLEditData,(char *)lParam); |
} |
return 0; |
#endif |
/* can i add it to message defined? */ |
#if 0 |
case WM_SETLINETEXT: |
{ |
int len,lineNO; |
PLINEDATA temp; |
|
if (dwStyle & ES_READONLY) |
return 0; |
|
pMLEditData = (PMLEDITDATA)GetWindowAdditionalData2(hWnd); |
|
len = strlen ((char*)lParam); |
lineNO = (int)wParam; |
temp = pMLEditData->head; |
len = min (len, pMLEditData->totalLen); |
|
if (pMLEditData->hardLimit >= 0) |
len = min (len, pMLEditData->hardLimit); |
while (temp) |
{ |
if(temp->lineNO == lineNO) |
{ |
temp->dataEnd = len; |
memcpy (temp->buffer, (char*)lParam, len); |
} |
temp = temp->next; |
} |
pMLEditData->editPos = 0; |
pMLEditData->caretPos = 0; |
pMLEditData->dispPos = 0; |
InvalidateRect (hWnd, NULL, FALSE); |
} |
return 0; |
#endif |
case WM_LBUTTONDBLCLK: |
break; |
|
case WM_LBUTTONDOWN: |
{ |
int newOff,lineNO; |
PLINEDATA temp; |
BOOL bScroll = FALSE; |
|
pMLEditData = (PMLEDITDATA)GetWindowAdditionalData2(hWnd); |
lineNO = edtGetLineNO (hWnd,pMLEditData, HIWORD (lParam)); |
if ( lineNO < 0 ) |
return 0; |
lineNO += pMLEditData->StartlineDisp; |
if (lineNO <= pMLEditData->EndlineDisp && lineNO <= pMLEditData->lines-1 ) |
{ |
temp = GetLineData(pMLEditData,lineNO); |
newOff = edtGetOffset (hWnd,pMLEditData,temp, LOWORD (lParam)); |
if(!edtIsACCharFromBegin(temp->buffer,temp->dataEnd,pMLEditData->dispPos)) |
{ |
bScroll = TRUE; |
pMLEditData->dispPos--; |
newOff = edtGetOffset (hWnd,pMLEditData,temp, LOWORD(lParam)+GetSysCharWidth(hWnd)/2); |
} |
if (newOff != pMLEditData->caretPos || lineNO != pMLEditData->editLine) { |
pMLEditData->editLine = temp->lineNO; |
pMLEditData->editPos = newOff +pMLEditData->dispPos; |
pMLEditData->caretPos = newOff; |
SetCaretPos (pMLEditData->caretPos * GetSysCharWidth (hWnd) |
+ pMLEditData->leftMargin, |
(pMLEditData->editLine - pMLEditData->StartlineDisp) * GetSysCharHeight(hWnd) |
+ pMLEditData->topMargin); |
} |
if(bScroll) |
InvalidateRect(hWnd,NULL,FALSE); |
} |
} |
break; |
|
case WM_LBUTTONUP: |
break; |
|
case WM_MOUSEMOVE: |
break; |
|
case WM_GETDLGCODE: |
return DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS; |
|
case EM_SETREADONLY: |
if (wParam) |
IncludeWindowStyle(hWnd,ES_READONLY); |
else |
ExcludeWindowStyle(hWnd,ES_READONLY); |
return 0; |
|
case EM_SETPASSWORDCHAR: |
pMLEditData = (PMLEDITDATA)GetWindowAdditionalData2(hWnd); |
|
if (pMLEditData->passwdChar != (int)wParam) { |
if (dwStyle & ES_PASSWORD) { |
pMLEditData->passwdChar = (int)wParam; |
InvalidateRect (hWnd, NULL, TRUE); |
} |
} |
return 0; |
|
case EM_GETPASSWORDCHAR: |
{ |
int* passwdchar; |
|
pMLEditData = (PMLEDITDATA)GetWindowAdditionalData2(hWnd); |
passwdchar = (int*) lParam; |
|
*passwdchar = pMLEditData->passwdChar; |
} |
return 0; |
|
case EM_LIMITTEXT: |
{ |
int newLimit = (int)wParam; |
|
if (newLimit >= 0) { |
pMLEditData = (PMLEDITDATA)GetWindowAdditionalData2(hWnd); |
if (pMLEditData->totalLen < newLimit) |
pMLEditData->hardLimit = -1; |
else |
pMLEditData->hardLimit = newLimit; |
} |
} |
return 0; |
|
default: |
return DefWindowProc (hWnd, message, wParam, lParam); |
break; |
} |
|
return 0; /* !DefaultControlProc (hWnd, message, wParam, lParam); */ |
} |
|
/fastfill.c
0,0 → 1,19
#include "windows.h" |
#include "wintools.h" |
/* |
* WIN Draw Library |
* Fast fill rectangle |
*/ |
|
/* |
* fast fill background (works with non-dithered colors only) |
*/ |
void WINAPI |
FastFillRect(HDC hdc,LPRECT lprect,COLORREF cr) |
{ |
COLORREF crOld; |
|
crOld = SetBkColor( hdc, cr); |
ExtTextOut( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED, lprect, NULL, 0, NULL); |
SetBkColor( hdc, crOld); |
} |
/insetr.c
0,0 → 1,14
#include "windows.h" |
#include "wintools.h" |
/* |
* WIN Draw Library |
*/ |
|
void WINAPI |
InsetR(LPRECT lprc,int h,int v) |
{ |
lprc->top += v; |
lprc->left += h; |
lprc->right -= 2*h-1; |
lprc->bottom -= 2*v-1; |
} |
/combobox.c
0,0 → 1,1785
/*-------------------------------------------------------------------------- |
** ComboBox.c Twin From: Twin/controls |
** |
** |
**------------------------- < License Information > ------------------------ |
** |
** This file was originally a part of Willows TWIN. Willows |
** TWIN was released under a Library GPL (LGPL). This permits |
** redistribution of this source code, provided that the full |
** TWIN license is in effect, and provided that all modifications |
** to this source code are made publicly available. |
** Please refer to Willows software (www.willows.com) or |
** LICENSE for full information. |
** |
** Under Twine, this file is also protected by an LGPL. Please |
** see LICENSE for full details on this license. |
** |
** |
** Copyright 1997 Willows Software, Inc. |
**------------------------ < File Content Description > -------------------- |
** |
** Module: controls/ComboBox.c |
** |
** Description: |
** |
** |
** Functions defined: |
** |
**------------------------- < Revision Information > ----------------------- |
** |
** Full Revision history at bottom of file |
** |
**--------------------------------------------------------------------------*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "windows.h" |
#include "windowsx.h" |
|
#define WinMalloc(n) malloc((n)) |
#define WinFree(p) free(p) |
|
#define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp) |
#define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp) |
#define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp) |
#define GET_WM_COMMAND_MPS(id, hwnd, cmd) \ |
(WPARAM)MAKELONG(id, cmd), (LONG)(hwnd) |
#define LOSHORT(x) (short int)LOWORD(x) |
#define Edit_SetSel(hwndCtl, ichStart, ichEnd) ((void)SendMessage((hwndCtl), EM_SETSEL, (ichStart), (ichEnd))) |
|
|
typedef struct { |
HFONT hFont; /* hFont used */ |
HWND hWndParent; /* parent window */ |
UINT nID; /* control ID */ |
WORD wStateFlags; /* combobox state flags */ |
UINT wStyle; /* this is a copy of LOWORD(style) */ |
BOOL bExtended; /* extended UI flag */ |
BOOL bRedraw; /* MiD - redraw flag, draw only if it's 1 */ |
HWND EditControl; /* edit/static control hWnd */ |
HWND ListBoxControl; /* listbox control hWnd */ |
RECT ButtonRect; /* local button rect (client) */ |
RECT ListBoxRect; /* listbox rect (screen) */ |
UINT uHeight; /* height of the normal state */ |
WNDPROC lpfnOldStatic; /* previous static wndproc */ |
UINT nListItems; /* ecw */ |
} COMBOBOX; |
|
#define CWD_LPCBDATA 0 |
#define CBC_EDITID 1 |
|
#define CSF_CAPTUREACTIVE 0x0001 |
#define CSF_LOCALBUTTONDOWN 0x0002 |
#define CSF_BUTTONDOWN 0x0004 |
#define CSF_LBOXBUTTONDOWN 0x0008 |
#define CSF_FOCUS 0x0010 /* MiD */ |
#define CSF_HASDROPPED 0x0020 /* weav */ |
|
#define SET_STATE(lp, wMask) (lp->wStateFlags |= (wMask)) |
#define CLEAR_STATE(lp, wMask) (lp->wStateFlags &= ~(wMask)) |
#define IS_SET(lp, wMask) (lp->wStateFlags & (wMask)) |
|
#define BOWNERDRAW(l) ((l)->wStyle & (CBS_OWNERDRAWFIXED|CBS_OWNERDRAWVARIABLE)) |
|
/********************************************** |
Styles: |
|
CBS_AUTOHSCROLL passed to the edit control |
CBS_DISABLENOSCROLL passed to the listbox control |
CBS_DROPDOWN |
CBS_DROPDOWNLIST |
CBS_HASSTRINGS passed to the listbox control |
CBS_NOINTEGRALHEIGHT passed to the listbox control |
CBS_OEMCONVERT passed to the edit control |
CBS_OWNERDRAWFIXED passed to the listbox control |
CBS_OWNERDRAWVARIABLE passed to the listbox control |
CBS_SIMPLE TODO |
CBS_SORT passed to the listbox control |
|
WS_VSCROLL passed to the listbox control |
|
*********************************************/ |
|
/********************************************** |
CBN_xxx messages to be added |
|
from mouse tracking... |
CBN_SELENDCANCEL TODO |
CBN_SELENDOK TODO |
|
*********************************************/ |
|
/* imported stuff */ |
#if 1 |
void |
Draw3DButtonRect(HDC hDC, HPEN hPenHigh, HPEN hPenShadow, |
RECT rc, BOOL fClicked) |
{ |
HPEN hPenOld; |
POINT lpt[6]; |
|
POINT p3[3]; |
int shrink=1; |
|
hPenOld = SelectObject(hDC, hPenShadow); |
if (fClicked) { |
lpt[0].x = lpt[1].x = rc.left; |
lpt[1].y = lpt[2].y = rc.top; |
lpt[2].x = rc.right-1; |
lpt[0].y = rc.bottom-1; |
Polyline(hDC,lpt,3); |
} |
else { |
lpt[0].x = lpt[1].x = rc.right-1; |
lpt[0].y = rc.top; |
lpt[1].y = lpt[2].y = rc.bottom-1; |
lpt[2].x = rc.left; |
lpt[3].x = rc.left+1; |
lpt[3].y = lpt[4].y = rc.bottom-2; |
lpt[4].x = lpt[5].x = rc.right-2; |
lpt[5].y = rc.top+1; |
Polyline(hDC,lpt,6); |
|
SelectObject(hDC, hPenHigh); |
lpt[0].x = rc.right-1; |
lpt[0].y = lpt[1].y = rc.top; |
lpt[1].x = lpt[2].x = rc.left; |
lpt[2].y = rc.bottom-1; |
lpt[3].x = lpt[4].x = rc.left+1; |
lpt[3].y = rc.bottom-2; |
lpt[4].y = lpt[5].y = rc.top+1; |
lpt[5].x = rc.right-2; |
Polyline(hDC,lpt,6); |
} |
|
SelectObject(hDC,GetStockObject(BLACK_BRUSH)); |
/* down */ |
p3[0].x= rc.left + ((rc.right-rc.left)/2) - 1; |
p3[0].y= rc.bottom - 4 - shrink; |
p3[1].x= rc.left + 2 + shrink - 1; |
p3[1].y= rc.bottom-(rc.bottom-rc.top) + 2 + shrink; |
p3[2].x= rc.left + ((rc.right-rc.left)-4) - shrink; |
p3[2].y= rc.bottom-(rc.bottom-rc.top) + 2 + shrink; |
Polygon(hDC,p3,3); |
|
SelectObject(hDC,hPenOld); |
} |
#endif |
|
#if 0 /* jmt: fix: no COMBOLBOX */ |
extern LRESULT DefLISTBOXProc(HWND, UINT, WPARAM, LPARAM); |
extern LRESULT ListboxCtrlProc(HWND, UINT, WPARAM, LPARAM); |
#endif |
|
#if 0 |
static HPEN GetSysColorPen(int color) |
{ |
return NULL; |
} |
static HBRUSH GetSysColorBrush(int color) |
{ |
return NULL; |
} |
#endif |
|
typedef HWND HWND32; |
|
#if 0 /* jmt: fix: no ownerdraw */ |
typedef HANDLE HCLASS32; |
static HCLASS32 FindClass(LPCSTR str, HINSTANCE hInstance) |
{ |
return NULL; |
} |
#endif |
|
#if 0 /* jmt: fix: no scrollbar */ |
static HWND TWIN_ConvertToSysScroll(HWND hwnd, BOOL status, LPPOINT pp) |
{ |
return NULL; |
} |
#endif |
extern HWND listwp; |
static HWND WindowFromPoint(POINT pt) |
{ |
HWND wp,wp1; |
int dx,dy,dx1,dy1; |
#if 0 |
return NULL; /* fix!! */ |
#else |
wp1=NULL; |
switch(sizeof(dx)) |
{ |
case 4: |
dx=0x7fffffff; |
dy=0x7fffffff; |
break; |
case 2: |
dx=0x7fff; |
dy=0x7fff; |
break; |
} |
for(wp=listwp; wp; wp=wp->next) |
{ |
if (wp->winrect.left <= pt.x && pt.x <= wp->winrect.right) |
{ |
dx1=(wp->winrect.right-pt.x); |
if (dx1<dx) |
{ |
wp1=wp; |
dx=dx1; |
} |
dx1=(pt.x-wp->winrect.left); |
if (dx1<dx) |
{ |
wp1=wp; |
dx=dx1; |
} |
} |
if (wp->winrect.top <= pt.y && pt.y <= wp->winrect.bottom) |
{ |
dy1=(wp->winrect.bottom-pt.y); |
if (dy1<dy) |
{ |
wp1=wp; |
dy=dy1; |
} |
dy1=(pt.y-wp->winrect.top); |
if (dy1<dy) |
{ |
wp1=wp; |
dy=dy1; |
} |
} |
} |
#endif |
return wp1; |
} |
|
/* internal stuff */ |
static void CBoxDrawButton(HWND,UINT,COMBOBOX *); |
static void CBoxSendMouseToLBox(COMBOBOX *, UINT, WPARAM, POINT); |
static void CBoxCapture(HWND, WORD); |
static void CBoxDrawEdit(COMBOBOX *, HWND, UINT); |
static void CBoxDrawStatic(COMBOBOX *, HWND, UINT); /* MiD */ |
|
/* handle specific CB messages */ |
static LRESULT DefCBProc(HWND , UINT , WPARAM , LPARAM ); |
|
#if 0 /* jmt: fix: no ownerdraw */ |
static WNDPROC lpComboBinToNat = 0; |
#endif |
|
static LRESULT CALLBACK |
DefComboboxProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
|
int WINAPI MwRegisterComboboxControl(HINSTANCE hInstance) |
{ |
WNDCLASS wc; |
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; |
wc.lpfnWndProc = (WNDPROC)DefComboboxProc; |
wc.cbClsExtra = 0; |
wc.cbWndExtra = 0; |
wc.hInstance = hInstance; |
wc.hIcon = NULL; |
wc.hCursor = 0; |
wc.hbrBackground= GetStockObject(WHITE_BRUSH); |
wc.lpszMenuName = NULL; |
wc.lpszClassName= "COMBOBOX"; |
|
return RegisterClass(&wc); |
} |
|
static LRESULT CALLBACK |
DefComboboxProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
{ |
PAINTSTRUCT ps; |
HDC hDC; |
TEXTMETRIC tm; |
#if 0 /* jmt: fix: no ownerdraw */ |
MEASUREITEMSTRUCT mis; |
#endif |
COMBOBOX *lp = (COMBOBOX *)NULL; |
LRESULT rc; |
HINSTANCE hInst; |
POINT cp,cpScreen,pp; |
UINT uiKey; |
LPCREATESTRUCT lpcs; |
#if 1 /* jmt: fix: no WM_WINDOWPOSCHANGING */ |
LPWINDOWPOS lpwp; |
#endif |
#if 0 /* jmt: fix: no ownerdraw */ |
HCLASS32 hComboClass32; |
LPMEASUREITEMSTRUCT lpmis; |
LPDRAWITEMSTRUCT lpdis; |
LPDELETEITEMSTRUCT lpdlis; |
#endif |
DWORD dwStyle,dwExStyle; |
WORD wEditWidth = 0,wEditHeight; |
WORD wCBN; |
#if 0 /* jmt: fix: no WM_SETFONT/WM_GETFONT */ |
RECT rcClient; |
#endif |
|
rc = CB_OKAY; |
if ((uMsg != WM_CREATE/*WM_NCCREATE*/) && /*(uMsg != WM_CONVERT) &&*/ |
!(lp = (COMBOBOX *)hWnd->userdata/*GetWindowLong(hWnd,CWD_LPCBDATA)*/)) |
return rc; |
|
switch(uMsg) { |
#if 0 |
case WM_SIZE: |
case WM_ENABLE: |
case WM_LBUTTONDBLCLK: |
case WM_COMPAREITEM: |
case WM_CUT: |
case WM_CLEAR: |
#endif |
|
case WM_SETFOCUS: |
SET_STATE(lp, CSF_FOCUS); |
if ((lp->wStyle & 0x0F) == CBS_DROPDOWNLIST) |
{ |
uiKey = (UINT)SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0L); |
CBoxDrawStatic(lp, hWnd, uiKey); |
} |
if (lp->EditControl) |
{ |
SetFocus(lp->EditControl); |
} |
break; |
|
case WM_KILLFOCUS: |
CLEAR_STATE(lp, CSF_FOCUS); |
if ((lp->wStyle & 0x0F) == CBS_DROPDOWNLIST) |
{ |
uiKey = (UINT)SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0L); |
CBoxDrawStatic(lp, hWnd, uiKey); |
} |
/* |
** Hide listbox when loosing focus to window other than |
** our own listbox... When wParam == 0 we "loose" the focus |
** to the scrollbar in a listbox! |
*/ |
if ((lp->wStyle & 0x0F) != CBS_SIMPLE && wParam != (WPARAM)lp->ListBoxControl && wParam != 0) |
SendMessage(hWnd, CB_SHOWDROPDOWN, 0, 0L); |
fprintf(stderr," 385: WM_KILLFOCUS\n"); |
break; |
|
#if 0 /* jmt: fix: no WM_KEYDOWN */ |
case WM_KEYDOWN: /* MiD 08/14/95 */ |
/* |
** We have to process this message in order to show |
** current selection in a static control for certain |
** keys. This doesn't affect combobox with an edit |
** control, since the edit traps all key messages. |
*/ |
{ |
int nCur = SendMessage(lp->ListBoxControl, LB_GETCURSEL,0, 0L); |
int nPrevCur = nCur; |
int nCount = SendMessage(lp->ListBoxControl, LB_GETCOUNT, 0, 0L); |
|
if (nCount == 0) |
break; |
|
switch(wParam) |
{ |
case VK_HOME: |
nCur = 0; |
break; |
|
case VK_END: |
nCur = nCount - 1; |
break; |
|
case VK_UP: |
nCur--; |
break; |
|
case VK_DOWN: |
nCur++; |
break; |
|
default: |
return 0L; |
} |
|
if (nCur >= nCount) |
nCur = nCount - 1; |
if (nCur < 0) |
nCur = 0; |
|
SendMessage(lp->ListBoxControl, LB_SETCURSEL, nCur, 0L); |
SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID, hWnd, CBN_SELCHANGE)); |
if (nCur != nPrevCur) |
/* ecw */ SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID, hWnd, CBN_SELENDOK)); |
InvalidateRect(hWnd, NULL, 1); |
break; |
} |
#endif /* WM_KEYDOWN */ |
|
case WM_CHAR: |
{ |
int nNewCur; |
int nOldCur; |
|
if (lp->EditControl) |
{ |
SendMessage(lp->EditControl, uMsg, wParam, lParam); |
} |
else { |
nOldCur = SendMessage(lp->ListBoxControl, LB_GETCURSEL,0, 0L); |
SendMessage(lp->ListBoxControl, uMsg, wParam, lParam); |
nNewCur = SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0L); |
if (nNewCur != nOldCur) |
{ |
SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID, hWnd, CBN_SELCHANGE)); |
InvalidateRect(hWnd, NULL, 1); |
} |
} |
break; |
} |
|
#if 0 /* jmt: fix: no WM_SETREDRAW */ |
case WM_SETREDRAW: |
lp->bRedraw = wParam; |
if (lp->EditControl) |
SendMessage(lp->EditControl, WM_SETREDRAW, wParam, lParam); |
if (lp->ListBoxControl) |
SendMessage(lp->ListBoxControl, WM_SETREDRAW, wParam, lParam); |
break; |
#endif |
case WM_CREATE: /*WM_NCCREATE:*/ |
lp = (COMBOBOX *)WinMalloc(sizeof(COMBOBOX)); |
memset((LPSTR)lp,'\0',sizeof(COMBOBOX)); |
|
/* save ptr to internal structure */ |
hWnd->userdata=(DWORD)lp; /* -SetWindowLong(hWnd, CWD_LPCBDATA, (LONG) lp); */ |
|
/* this is for CreateWindow calls */ |
hInst = NULL; /* -GetWindowInstance(hWnd); */ |
|
/* fill in the internal structure */ |
lpcs = (LPCREATESTRUCT)lParam; |
lp->bRedraw = 1; |
lp->wStateFlags = 0; |
lp->wStyle = (UINT)LOWORD(lpcs->style); |
if (!BOWNERDRAW(lp)) |
lp->wStyle |= CBS_HASSTRINGS; |
lp->bExtended = TRUE; |
lp->hFont = 0; |
lp->hWndParent = lpcs->hwndParent; |
lp->nID = (UINT)lpcs->hMenu; |
|
#if 0 /* jmt: fix: no ownerdraw */ |
/* calc the height of the edit/static control */ |
if (0) /* (BOWNERDRAW(lp)) */ |
{ |
mis.CtlType = ODT_COMBOBOX; |
mis.CtlID = (UINT)lpcs->hMenu; |
mis.itemID = (UINT)-1; |
mis.itemData = 0L; |
SendMessage(lpcs->hwndParent, WM_MEASUREITEM, (WPARAM)lpcs->hMenu, (LPARAM)&mis); |
/*** wEditHeight = (WORD)mis.itemHeight + 2; ***/ |
} |
#endif /* ownerdraw */ |
|
/* get system font dimensions */ |
hDC = GetDC((HWND)0); |
GetTextMetrics(hDC,&tm); |
ReleaseDC((HWND)0,hDC); |
|
/* allow different fonts to fit, don't hard code */ |
/* otherwise big fonts won't fit. */ |
/*****wEditHeight = ((tm.tmHeight - tm.tmInternalLeading)*7)/4;*****/ |
wEditHeight = tm.tmHeight + tm.tmInternalLeading * 3; |
|
lp->uHeight = (UINT)wEditHeight; |
|
if ((lp->wStyle & 0x0F) != CBS_SIMPLE) |
{ |
lp->ButtonRect.top = 0; |
lp->ButtonRect.left = lpcs->cx - 1 - GetSystemMetrics(SM_CXVSCROLL); |
lp->ButtonRect.right = lpcs->cx; |
lp->ButtonRect.bottom = wEditHeight; |
/* for CBS_DROPDOWN/DROPDOWNLIST resize the window */ |
SetWindowPos(hWnd, 0, |
0, 0, lpcs->cx, (int)wEditHeight, |
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW); |
} |
else SetRectEmpty(&lp->ButtonRect); |
|
if ((lp->wStyle & 0xf) != CBS_DROPDOWNLIST) |
{ /* EDIT field - calc edit control style */ |
dwStyle = WS_CHILD | WS_VISIBLE | WS_BORDER; |
if (lp->wStyle & CBS_AUTOHSCROLL) |
dwStyle |= ES_AUTOHSCROLL; |
if (lp->wStyle & CBS_OEMCONVERT) |
dwStyle |= ES_OEMCONVERT; |
|
if ((lp->wStyle & 0x0F) == CBS_SIMPLE) |
{ |
fprintf(stderr," 528: wEditWidth = lpcs->cx=%d\n",lpcs->cx); |
wEditWidth = lpcs->cx; |
} |
else /* ?if ((lp->wStyle & 0xf) == CBS_DROPDOWN) */ |
{ |
fprintf(stderr," 533: wEditWidth = lp->ButtonRect.left - 5=%d;\n",lp->ButtonRect.left - 5); |
wEditWidth = lp->ButtonRect.left - 5; |
} |
/* create edit control */ |
lp->EditControl = CreateWindow("EDIT", NULL, dwStyle, |
0, 0, wEditWidth, wEditHeight, |
hWnd, (HMENU)CBC_EDITID, |
hInst,(LPVOID)NULL); |
} |
else /* CBS_DROPDOWN -- static instead of edit */ |
lp->EditControl = 0; |
|
/* listbox style */ |
/* jmt: fix: no WS_EX_SAVEBITS, WS_EX_NOCAPTURE, WS_EX_POPUPMENU */ |
dwExStyle = 0L; /* WS_EX_SAVEBITS | WS_EX_NOCAPTURE | WS_EX_POPUPMENU; */ |
dwStyle = WS_BORDER | LBS_NOTIFY ; /* | LBS_COMBOLBOX; */ |
if ((lp->wStyle & 0xf) == CBS_SIMPLE) |
dwStyle |= WS_VISIBLE | WS_CHILD; |
else |
dwStyle |= WS_POPUP; |
#if 0 |
if (lp->wStyle & CBS_DISABLENOSCROLL) |
dwStyle |= LBS_DISABLENOSCROLL; |
#endif |
if (lp->wStyle & CBS_HASSTRINGS) |
dwStyle |= LBS_HASSTRINGS; |
if (lp->wStyle & CBS_NOINTEGRALHEIGHT) |
dwStyle |= LBS_NOINTEGRALHEIGHT; |
if (lp->wStyle & CBS_OWNERDRAWFIXED) |
dwStyle |= LBS_OWNERDRAWFIXED; |
if (lp->wStyle & CBS_OWNERDRAWVARIABLE) |
dwStyle |= LBS_OWNERDRAWVARIABLE; |
if (lp->wStyle & CBS_SORT) |
dwStyle |= LBS_SORT; |
if (lpcs->style & WS_VSCROLL) |
dwStyle |= WS_VSCROLL; |
|
/* calc listbox dimensions and position */ |
if ((lp->wStyle & 0xf) == CBS_SIMPLE) { |
lp->ListBoxRect.left = 5; |
lp->ListBoxRect.top = wEditHeight - 1; |
lp->ListBoxRect.right = lpcs->cx; |
lp->ListBoxRect.bottom = lpcs->cy - 2; |
} else { |
lp->ListBoxRect.left = lpcs->x; |
lp->ListBoxRect.right = lp->ListBoxRect.left + lpcs->cx - 1; |
lp->ListBoxRect.top = lpcs->y + wEditHeight - 1; |
lp->ListBoxRect.bottom = lp->ListBoxRect.top + lpcs->cy + 1; |
if ((lp->wStyle & 0x0F) == CBS_DROPDOWN) { |
lp->ListBoxRect.left += 5; |
} |
} |
#ifdef LATER |
cp.x = ((lp->wStyle & 0xf) == CBS_DROPDOWNLIST)?0:5; |
cp.y = wEditHeight - 1; |
if ((lp->wStyle & 0xf) != CBS_SIMPLE) |
ClientToScreen(hWnd,&cp); |
lp->ListBoxRect.left = cp.x; |
lp->ListBoxRect.top = cp.y; |
lp->ListBoxRect.right = cp.x + lpcs->cx; |
if ((lp->wStyle & 0xf) != CBS_DROPDOWNLIST) |
lp->ListBoxRect.right -= 5; |
lp->ListBoxRect.bottom = lp->ListBoxRect.top + lpcs->cy - |
wEditHeight + 1; |
#endif |
|
lp->ListBoxControl = CreateWindowEx(dwExStyle,"LISTBOX",/*"COMBOLBOX",*/ |
NULL, dwStyle, |
lp->ListBoxRect.left, lp->ListBoxRect.top, |
lp->ListBoxRect.right - lp->ListBoxRect.left, |
lp->ListBoxRect.bottom - lp->ListBoxRect.top, |
hWnd, 0, |
hInst,(LPVOID)NULL); |
#if MWCLIENT |
#if 0 |
GrLowerWindow(lp->ListBoxControl->wid); |
#endif |
MwLowerWindow(lp->ListBoxControl); |
#endif |
#ifdef LATER |
/* Microsoft Word 6.0 wants to see COMBOLBOX on top */ |
/* of Z-order... */ |
if (dwStyle & WS_POPUP) |
{ |
SetWindowPos(lp->ListBoxControl, HWND_TOP, |
0, 0, 0, 0, |
SWP_NOREDRAW | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE); |
} |
#endif |
|
#if 0 /* jmt: fix: no HWND32(LPWININFO) */ |
/* physically expand client window, |
if there is a scroll style |
*/ |
if (lpcs->style & WS_VSCROLL) |
{ |
HWND32 hWnd32 = GETHWND32(hWnd); |
|
SetRectEmpty(&hWnd32->rcNC); |
|
hWnd32->wWidth = (WORD) hWnd32->rWnd.right-hWnd32->rWnd.left; |
hWnd32->wHeight = (WORD)hWnd32->rWnd.bottom-hWnd32->rWnd.top; |
RELEASEWININFO(hWnd32); |
} |
#endif |
/* |
** Finally turn off border drawing and WM_?SCROLL styles to prevent creation |
** of system scrollbars. |
*/ |
dwStyle = GetWindowLong(hWnd, GWL_STYLE); |
dwStyle &= ~(WS_VSCROLL | WS_HSCROLL | WS_BORDER | WS_DLGFRAME | WS_THICKFRAME); |
SetWindowLong(hWnd, GWL_STYLE, dwStyle); |
lp->nListItems = 0; |
return TRUE; |
|
case WM_DESTROY: /*WM_NCDESTROY:*/ |
if (IsWindow(lp->ListBoxControl)) |
DestroyWindow(lp->ListBoxControl); |
if (IsWindow(lp->EditControl)) |
DestroyWindow(lp->EditControl); |
WinFree((LPSTR)lp); |
return 0L; |
|
case WM_GETDLGCODE: |
return (LRESULT)(DLGC_WANTCHARS|DLGC_WANTARROWS); |
|
/* jmt: twine->mwin bug fixed: */ |
case WM_NCLBUTTONDOWN: /* jmt: a must */ |
#if 0 /* twine->mw buggy */ |
case WM_LBUTTONDOWN: |
#endif |
if ((lp->wStyle & 0xf) == CBS_SIMPLE) |
break; |
|
cp.x = (int)(short)LOWORD(lParam); |
cp.y = (int)(short)HIWORD(lParam); |
#if 1 /* WM_NCLBUTTONDOWM: */ |
ScreenToClient(hWnd, &cp); /* jmt: a must */ |
#endif |
if (!IS_SET(lp, CSF_CAPTUREACTIVE)) /* no listbox yet */ |
{ |
/* click on a button or anywhere if it's dropdown combo */ |
if (PtInRect(&lp->ButtonRect, cp) || |
(lp->wStyle & 0x0F) == CBS_DROPDOWNLIST) |
{ |
if (PtInRect(&lp->ButtonRect, cp)) |
CBoxDrawButton(hWnd, 1, lp); |
|
cp.x = ((lp->wStyle & 0xf) != CBS_DROPDOWNLIST) ? 5 : 0; |
cp.y = lp->uHeight - 1; |
|
ClientToScreen(hWnd, &cp); |
|
fprintf(stderr," (1)lp->ListBoxRect:(%d,%d,%d,%d)\n", |
lp->ListBoxRect.left, |
lp->ListBoxRect.top, |
lp->ListBoxRect.right, |
lp->ListBoxRect.bottom); |
|
OffsetRect(&lp->ListBoxRect, cp.x - lp->ListBoxRect.left, cp.y - lp->ListBoxRect.top); |
|
fprintf(stderr," (2)lp->ListBoxRect:(%d,%d,%d,%d)\n", |
lp->ListBoxRect.left, |
lp->ListBoxRect.top, |
lp->ListBoxRect.right, |
lp->ListBoxRect.bottom); |
|
SetWindowPos(lp->ListBoxControl, HWND_TOP, /*0,*/ |
cp.x, cp.y, 0, 0, |
SWP_NOSIZE | /*SWP_NOZORDER |*/ SWP_NOACTIVATE); |
|
SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID,hWnd,CBN_DROPDOWN)); |
/* ECW added following conditional... 4/4/96 */ |
/* JMT following conditional is a must for microwindows 8/14/2k */ |
if (1) /* -(!IS_SET(lp, CSF_HASDROPPED)) jmt: a must */ |
{ |
/* ??first time it drops down, size it to hold all items?? */ |
|
int nitems = SendMessage(lp->ListBoxControl,LB_GETCOUNT,0,0L); |
#if 0 |
/* resize if too small, in this case, also do too long */ |
if (lp->ListBoxRect.bottom - lp->ListBoxRect.top < |
((lp->uHeight-2) * nitems)) |
{ |
#endif |
nitems = (nitems > 12 ? 12 : nitems); /* a dozen, max */ |
|
#if 0 /* twine->mw buggy? */ |
lp->ListBoxRect.bottom = |
lp->ListBoxRect.top + ((lp->uHeight-2) * nitems); |
#endif |
fprintf(stderr," (2.5)lp->ListBoxRect:(%d,%d,%d,%d)\n", |
lp->ListBoxRect.left, |
lp->ListBoxRect.top, |
lp->ListBoxRect.right, |
lp->ListBoxRect.bottom); |
|
/* jmt: twine->mwin bug fixed: */ |
fprintf(stderr," 706: fixed: SetWindowPos(lp->ListBoxControl,,%d,%d,...)\n",cp.x,cp.y); |
#if 0 /* twine->mwin bug */ |
SetWindowPos(lp->ListBoxControl,HWND_TOP,0,0, |
lp->ListBoxRect.right - lp->ListBoxRect.left, |
lp->ListBoxRect.bottom - lp->ListBoxRect.top, |
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); |
#else /* jmt: twine->mwin bug fixed: */ |
SetWindowPos(lp->ListBoxControl,HWND_TOP,cp.x,cp.y, |
lp->ListBoxRect.right - lp->ListBoxRect.left, |
lp->ListBoxRect.bottom - lp->ListBoxRect.top, |
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); |
#endif |
|
#if 0 |
} |
#endif |
SET_STATE(lp, CSF_HASDROPPED); |
} |
/* End of addition */ |
ShowWindow(lp->ListBoxControl, SW_SHOW); |
#if 0 /* orig(twine) */ |
SetFocus(lp->ListBoxControl); |
#else /* jmt: mwclient */ |
SetForegroundWindow(lp->ListBoxControl); |
#endif |
CBoxCapture(hWnd, 1); |
SET_STATE(lp, CSF_CAPTUREACTIVE); |
SET_STATE(lp, CSF_BUTTONDOWN); |
} |
} |
else |
{ /* there is a listbox visible */ |
HWND hwndNewFocus = 0; |
|
cpScreen = cp; |
|
if ((lp->wStyle & 0xf) != CBS_SIMPLE) |
{ |
ClientToScreen(hWnd, &cpScreen); |
hwndNewFocus = WindowFromPoint(cpScreen); |
} |
|
fprintf(stderr," (3)lp->ListBoxRect:(%d,%d,%d,%d)\n", |
lp->ListBoxRect.left, |
lp->ListBoxRect.top, |
lp->ListBoxRect.right, |
lp->ListBoxRect.bottom); |
|
if (PtInRect(&lp->ListBoxRect, cpScreen)) |
{ |
CBoxSendMouseToLBox(lp, WM_LBUTTONDOWN, wParam, cpScreen); |
} |
else |
{ |
if (PtInRect(&lp->ButtonRect, cp)) |
CBoxDrawButton(hWnd, 0, lp); |
if ((lp->wStyle & 0x0F) == CBS_DROPDOWN && hwndNewFocus == lp->EditControl) |
/* don't close listbox */; |
else { |
SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID,hWnd,CBN_CLOSEUP)); |
|
fprintf(stderr," 802: (hide) SetWindowPos(lp->ListBoxControl, , 0, 0, 0, 0,..)\n"); |
|
SetWindowPos(lp->ListBoxControl, 0, |
0, 0, 0, 0, |
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_HIDEWINDOW); |
#if MWCLIENT |
MwLowerWindow(lp->ListBoxControl); |
#endif |
CBoxCapture(hWnd, 0); |
CLEAR_STATE(lp, CSF_BUTTONDOWN); |
} |
CLEAR_STATE(lp, CSF_CAPTUREACTIVE); |
|
if (hwndNewFocus && hwndNewFocus != hWnd) |
{ |
ScreenToClient(hwndNewFocus, &cpScreen); |
SetFocus(hwndNewFocus); |
|
SendMessage(hwndNewFocus, WM_LBUTTONDOWN, wParam, MAKELONG(cpScreen.x, cpScreen.y)); |
} |
} /* !(PtInRect(&lp->ListBoxRect, cpScreen)) */ |
} |
break; |
|
/* jmt: twine->mwin bug fixed: */ |
case WM_NCMOUSEMOVE: |
#if 0 /* jmt: twine->mw buggy */ |
case WM_MOUSEMOVE: |
#endif |
if (!IS_SET(lp,CSF_BUTTONDOWN) && ((lp->wStyle & 0xf) == CBS_SIMPLE)) |
break; |
|
cp.x = (int)(short)LOWORD(lParam); |
cp.y = (int)(short)HIWORD(lParam); |
#if 1 /* WM_NCMOUSEMOVE: */ |
ScreenToClient(hWnd, &cp); /* jmt: a must */ |
#endif |
|
if (IS_SET(lp, CSF_CAPTUREACTIVE)) |
{ |
if (PtInRect(&lp->ButtonRect,cp)) |
{ |
if (!IS_SET(lp, CSF_LOCALBUTTONDOWN)) |
CBoxDrawButton(hWnd, 1, lp); |
break; |
} |
if ((lp->wStyle & 0xf) != CBS_SIMPLE) |
ClientToScreen(hWnd,&cp); |
if (PtInRect(&lp->ListBoxRect,cp)) |
{ |
CBoxSendMouseToLBox(lp,WM_MOUSEMOVE,wParam,cp); |
} |
if (IS_SET(lp,CSF_LOCALBUTTONDOWN) && ((lp->wStyle & 0xf) != CBS_SIMPLE)) |
CBoxDrawButton(hWnd,0,lp); |
} |
break; |
|
/* jmt: twine->mwin bug fixed: */ |
case WM_NCLBUTTONUP: |
#if 0 /* twine->mw buggy */ |
case WM_LBUTTONUP: |
#endif |
if (!IS_SET(lp, CSF_CAPTUREACTIVE)) |
break; |
|
cp.x = (int)(short)LOWORD(lParam); |
cp.y = (int)(short)HIWORD(lParam); |
#if 1 /* WM_NCLBUTTONUP */ |
ScreenToClient(hWnd, &cp); /* jmt: a must */ |
#endif |
|
CLEAR_STATE(lp,CSF_BUTTONDOWN); |
|
if (PtInRect(&lp->ButtonRect, cp)) |
/*(lp->wStyle & 0x0F) == CBS_DROPDOWNLIST)*/ |
{ |
if (PtInRect(&lp->ButtonRect, cp)) |
CBoxDrawButton(hWnd, 0, lp); |
if (IS_SET(lp, CSF_LBOXBUTTONDOWN)) |
{ |
if ((lp->wStyle & 0xf) != CBS_SIMPLE) |
ClientToScreen(hWnd, &cp); |
CBoxSendMouseToLBox(lp, WM_LBUTTONUP, wParam, cp); |
CLEAR_STATE(lp,CSF_LBOXBUTTONDOWN); |
} |
break; |
} |
if ((lp->wStyle & 0xf) != CBS_SIMPLE) |
ClientToScreen(hWnd, &cp); |
|
if (PtInRect(&lp->ListBoxRect, cp)) |
{ |
uiKey = (UINT)SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0); |
if (uiKey != (UINT)LB_ERR) |
{ |
if (lp->EditControl) |
{ |
SetFocus(lp->EditControl); |
|
CBoxDrawEdit(lp, hWnd, uiKey); |
} |
else { |
SetFocus(hWnd); |
|
CBoxDrawStatic(lp, hWnd, uiKey); |
} |
|
/* LATER check the WS_EX_NOPARENTNOTIFY bit in ext style.*/ |
/* ecw */ SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID,hWnd,CBN_SELENDOK)); |
SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID,hWnd,CBN_CLOSEUP)); |
|
fprintf(stderr," 844: (hide) SetWindowPos(lp->ListBoxControl, , 0, 0, 0, 0,..)\n"); |
|
SetWindowPos(lp->ListBoxControl, 0, |
0, 0, 0, 0, |
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_HIDEWINDOW); |
|
CBoxCapture(hWnd, 0); |
CLEAR_STATE(lp,CSF_CAPTUREACTIVE); |
} /* uiKey ok */ |
|
CBoxSendMouseToLBox(lp, WM_LBUTTONUP, wParam, cp); |
CLEAR_STATE(lp,CSF_LBOXBUTTONDOWN); |
#if MWCLIENT |
#if 0 |
GrLowerWindow(lp->ListBoxControl->wid); |
#endif |
MwLowerWindow(lp->ListBoxControl); |
#endif |
} |
else /* clicked somewhere outside button or listbox - |
** the listbox should stay intact... MiD |
*/ |
if (IS_SET(lp, CSF_LBOXBUTTONDOWN)) |
{ |
if ((lp->wStyle & 0xf) != CBS_SIMPLE) |
ClientToScreen(hWnd, &cp); |
CBoxSendMouseToLBox(lp, WM_LBUTTONUP, wParam, cp); |
CLEAR_STATE(lp,CSF_LBOXBUTTONDOWN); |
} |
break; |
|
case WM_ERASEBKGND: |
return 1L; |
|
case WM_PAINT: |
BeginPaint(hWnd,&ps); |
EndPaint(hWnd,&ps); |
|
if (!IsWindowVisible(hWnd) || !lp->bRedraw) |
return 0L; |
|
if ((lp->wStyle & 0xf) != CBS_SIMPLE) |
CBoxDrawButton(hWnd, IS_SET(lp,CSF_LOCALBUTTONDOWN), lp); |
uiKey = (UINT)SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0); |
if (lp->EditControl) |
CBoxDrawEdit(lp, hWnd, uiKey); |
else CBoxDrawStatic(lp, hWnd, uiKey); |
return 0L; |
|
case WM_COMMAND: |
if (GET_WM_COMMAND_ID(wParam,lParam) == CBC_EDITID) { |
/* edit/static control notifications */ |
switch((short)GET_WM_COMMAND_CMD(wParam,lParam)) { |
case EN_SETFOCUS: |
#ifdef LATER |
wCBN = CBN_SETFOCUS; |
#else |
wCBN = 0; |
#endif |
break; |
case EN_KILLFOCUS: |
wCBN = CBN_KILLFOCUS; |
break; |
case EN_CHANGE: |
{ |
int index = 0; |
char sz[128]; |
/* |
** Advance listbox |
** selection until there is string match. One first mismatch |
** listbox advances to its first item. |
*/ |
SendMessage(lp->EditControl, WM_GETTEXT, sizeof(sz)-1, (LPARAM)sz); |
if (/*l*/strlen(sz) > 0/*L*/) |
index = (int)SendMessage(lp->ListBoxControl, LB_FINDSTRING, -1, (LPARAM)sz); |
if (index == LB_ERR) |
index = 0; |
SendMessage(lp->ListBoxControl, LB_SETTOPINDEX, index, 0L); |
wCBN = CBN_EDITCHANGE; |
break; |
} |
case EN_UPDATE: |
wCBN = CBN_EDITUPDATE; |
break; |
case EN_ERRSPACE: |
wCBN = CBN_ERRSPACE; |
break; |
default: |
wCBN = 0; |
break; |
} |
if (wCBN) |
return SendMessage(lp->hWndParent,WM_COMMAND, |
GET_WM_COMMAND_MPS(lp->nID,hWnd,wCBN)); |
else |
return rc; |
} |
if (GET_WM_COMMAND_ID(wParam,lParam) == 0) { |
/* listbox notifications */ |
switch ((short)GET_WM_COMMAND_CMD(wParam,lParam)) { |
case LBN_ERRSPACE: |
wCBN = CBN_ERRSPACE; |
break; |
case LBN_SELCHANGE: |
if ((lp->wStyle & 0xf) == CBS_SIMPLE) |
{ |
uiKey = (UINT)SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0); |
if (uiKey != (UINT)LB_ERR) |
if (lp->EditControl) |
{ |
CBoxDrawEdit(lp, hWnd, uiKey); |
} |
} |
wCBN = CBN_SELCHANGE; |
break; |
case LBN_DBLCLK: |
wCBN = CBN_DBLCLK; |
break; |
case LBN_SELCANCEL: /* TODO */ |
wCBN = 0; |
break; |
case LBN_SETFOCUS: |
wCBN = CBN_SETFOCUS; |
break; |
case LBN_KILLFOCUS: |
wCBN = CBN_KILLFOCUS; |
break; |
default: |
wCBN = 0; |
break; |
} |
if (wCBN) |
return SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID,hWnd,wCBN)); |
else |
return rc; |
} |
break; |
|
case WM_GETTEXT: |
if ( lp->EditControl ) |
return SendMessage(lp->EditControl,uMsg,wParam,lParam); |
else if ( lp->ListBoxControl ) { |
WPARAM sel, len; |
|
sel = (WPARAM)SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0); |
if ( sel != (WPARAM)LB_ERR ) { |
len = (WPARAM)SendMessage(lp->ListBoxControl, LB_GETTEXTLEN, 0, 0); |
if ( len <= wParam ) |
return SendMessage(lp->ListBoxControl, LB_GETTEXT, sel, lParam); |
} |
} |
return CB_ERR; |
|
case WM_GETTEXTLENGTH: |
if ( lp->EditControl ) |
return SendMessage(lp->EditControl,uMsg,wParam,lParam); |
else if ( lp->ListBoxControl ) { |
WPARAM sel; |
|
sel = (WPARAM)SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0); |
if ( sel != (WPARAM)LB_ERR ) |
return SendMessage(lp->ListBoxControl, LB_GETTEXTLEN, sel, 0); |
} |
return CB_ERR; |
|
case WM_SETTEXT: |
if ( lp->EditControl ) |
return SendMessage(lp->EditControl,uMsg,wParam,lParam); |
return CB_ERR; |
|
#if 0 /* jmt: fix: no WM_SETFONT/WM_GETFONT */ |
case WM_SETFONT: |
lp->hFont = (HFONT)wParam; |
|
hDC = GetDC(hWnd); |
SelectObject(hDC,lp->hFont); |
GetTextMetrics(hDC,&tm); |
ReleaseDC(hWnd,hDC); |
wEditHeight = tm.tmHeight + 3 * tm.tmInternalLeading; |
|
if (wEditHeight == lp->uHeight) |
return 0L; |
|
lp->uHeight = (UINT)wEditHeight; |
lp->ButtonRect.bottom = wEditHeight; |
/* |
** The following SetWindowPos causes WM_WINDOWPOSCHANGING message |
** where child windows are resized and/or moved. |
*/ |
ShowWindow(hWnd, SW_HIDE); |
GetClientRect(hWnd,&rcClient); |
if ((lp->wStyle & 0xf) != CBS_SIMPLE) |
SetWindowPos(hWnd, 0, |
0, 0, rcClient.right, (int)wEditHeight, |
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW); |
else SetWindowPos(hWnd, 0, |
0, 0, rcClient.right, (int)wEditHeight + lp->ListBoxRect.bottom - lp->ListBoxRect.top + 1, |
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW); |
ShowWindow(hWnd, SW_SHOWNA); |
|
if (lp->EditControl) |
SendMessage(lp->EditControl, WM_SETFONT, wParam,lParam); |
SendMessage(lp->ListBoxControl, WM_SETFONT, wParam,lParam); |
|
if(LOWORD(lParam)) |
RedrawWindow(hWnd,(const RECT *)0,(HRGN)0, |
RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW ); |
return (LRESULT)0; |
|
case WM_GETFONT: |
return lp->hFont; |
#endif /* WM_SETFONT/WM_GETFONT */ |
|
case WM_MOVE: /*WM_WINDOWPOSCHANGING:*/ |
#if 0 |
lpwp = (LPWINDOWPOS)lParam; |
#else |
pp.x=LOWORD(lParam); |
pp.y=HIWORD(lParam); |
#endif |
if (1)/*(lpwp)*/ { |
if (1)/*(!(lpwp->flags & SWP_NOSIZE))*/ { |
lp->ButtonRect.right = (hWnd->winrect.right-hWnd->winrect.left); /* lpwp->cx; */ |
if ((lp->wStyle & 0xf) == CBS_SIMPLE) |
lp->ButtonRect.left = lp->ButtonRect.right; |
else lp->ButtonRect.left = (hWnd->winrect.right-hWnd->winrect.left)/*lpwp->cx*/ - 1 - |
GetSystemMetrics(SM_CXVSCROLL); |
|
if (lp->EditControl) |
{ |
wEditWidth = lp->ButtonRect.left + 1; |
if ((lp->wStyle & 0xf) == CBS_SIMPLE) |
wEditWidth --; |
if ((lp->wStyle & 0xf) == CBS_DROPDOWN) |
wEditWidth -= 5; |
SetWindowPos(lp->EditControl,(HWND)0, |
0,0, |
wEditWidth, lp->uHeight, |
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER); |
} |
if (lp->ListBoxControl) |
{ |
if ((lp->wStyle & 0x0F) == CBS_SIMPLE) |
{ |
lp->ListBoxRect.left = 5; |
lp->ListBoxRect.top = lp->uHeight - 1; |
lp->ListBoxRect.right = (hWnd->winrect.right-hWnd->winrect.left); /* lpwp->cx; */ |
lp->ListBoxRect.bottom = (hWnd->winrect.bottom-hWnd->winrect.top)/*lpwp->cy*/ - 2; |
} |
else { |
POINT cp; |
cp.x = 0; |
cp.y = lp->uHeight - 1; |
ClientToScreen(hWnd, &cp); |
OffsetRect(&lp->ListBoxRect, cp.x - lp->ListBoxRect.left, cp.y - lp->ListBoxRect.top); |
|
lp->ListBoxRect.right = lp->ListBoxRect.left + (hWnd->winrect.right-hWnd->winrect.left)/*lpwp->cx*/; |
if ((lp->wStyle & 0xf) != CBS_DROPDOWNLIST) |
lp->ListBoxRect.right -= 5; |
} |
|
SetWindowPos(lp->ListBoxControl,(HWND)0, |
lp->ListBoxRect.left, lp->ListBoxRect.top, |
lp->ListBoxRect.right - lp->ListBoxRect.left, |
lp->ListBoxRect.bottom - lp->ListBoxRect.top, |
SWP_NOACTIVATE|SWP_NOZORDER); |
} |
#if 0 /* jmt: fix: no WM_WINDOWPOSCHANGING */ |
/* the height of the normal state stays the same */ |
if ((lp->wStyle & 0xf) != CBS_SIMPLE) |
lpwp->cy = (int)lp->uHeight; |
#endif |
} |
} |
return (LRESULT)0; |
|
case WM_WINDOWPOSCHANGED: |
DefWindowProc(hWnd,uMsg,wParam,lParam); |
lpwp = (LPWINDOWPOS)lParam; |
if (lpwp) { |
if (!(lpwp->flags & SWP_NOSIZE)) /* TODO */ |
#if 0 |
RedrawWindow(hWnd,(const RECT *)0,(HRGN)0, |
RDW_INVALIDATE|RDW_ERASE); |
#else |
InvalidateRect(hWnd,NULL,TRUE); |
#endif |
} |
return (LRESULT)0; |
|
#if 0 /* jmt: fix: no ownerdraw */ |
/*********************************************/ |
/* ownerdraw stuff */ |
/*********************************************/ |
case WM_DRAWITEM: |
lpdis = (LPDRAWITEMSTRUCT)lParam; |
lpdis->CtlType = ODT_COMBOBOX; |
lpdis->CtlID = lp->nID; |
lpdis->hwndItem = hWnd; |
return SendMessage(lp->hWndParent,WM_DRAWITEM, |
(WPARAM)lp->nID,lParam); |
|
case WM_MEASUREITEM: |
lpmis = (LPMEASUREITEMSTRUCT)lParam; |
lpmis->CtlType = ODT_COMBOBOX; |
lpmis->CtlID = lp->nID; |
return SendMessage(lp->hWndParent,WM_MEASUREITEM, |
(WPARAM)lp->nID,lParam); |
|
case WM_DELETEITEM: |
lpdlis = (LPDELETEITEMSTRUCT)lParam; |
lpdlis->CtlType = ODT_COMBOBOX; |
lpdlis->CtlID = lp->nID; |
lpdlis->hwndItem = hWnd; |
return SendMessage(lp->hWndParent,WM_DELETEITEM, |
(WPARAM)lp->nID,lParam); |
|
case WM_CONVERT: |
if (!lpComboBinToNat) { |
hComboClass32 = FindClass("COMBOBOX",0); |
lpComboBinToNat = (WNDPROC)GetClassHandleLong( |
hComboClass32,GCL_BINTONAT); |
} |
if (lpComboBinToNat) |
return lpComboBinToNat(hWnd, uMsg, wParam, lParam); |
else |
return (LRESULT)0; |
#endif /* ownerdraw */ |
|
default: |
return DefCBProc( hWnd, uMsg, wParam, lParam); |
} |
return rc; |
} |
|
/************************************************************************ |
** |
************************************************************************/ |
static LRESULT DefCBProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
{ |
int len,index; |
COMBOBOX *lp; |
char *selection; |
int rc; |
POINT cp; |
|
lp = (COMBOBOX *) hWnd->userdata/*GetWindowLong(hWnd,CWD_LPCBDATA)*/; |
switch(uMsg) { |
/*********************************************/ |
/* messages specific to the list box control */ |
/*********************************************/ |
case CB_ADDSTRING: |
lp->nListItems++; /* shd. test for successful return */ |
return SendMessage(lp->ListBoxControl,LB_ADDSTRING, |
wParam,lParam); |
|
case CB_DELETESTRING: |
if (lp->nListItems) |
lp->nListItems--; |
return SendMessage(lp->ListBoxControl,LB_DELETESTRING, |
wParam,lParam); |
|
case CB_DIR: |
return SendMessage(lp->ListBoxControl,LB_DIR, |
wParam,lParam); |
|
case CB_FINDSTRING: |
return SendMessage(lp->ListBoxControl,LB_FINDSTRING, |
wParam,lParam); |
|
case CB_FINDSTRINGEXACT: |
return SendMessage(lp->ListBoxControl,LB_FINDSTRINGEXACT, |
wParam,lParam); |
|
case CB_GETCOUNT: |
return SendMessage(lp->ListBoxControl,LB_GETCOUNT, |
wParam,lParam); |
|
case CB_GETCURSEL: |
return SendMessage(lp->ListBoxControl,LB_GETCURSEL, |
wParam,lParam); |
|
case CB_GETITEMDATA: |
return SendMessage(lp->ListBoxControl,LB_GETITEMDATA, |
wParam,lParam); |
|
case CB_GETITEMHEIGHT: |
return SendMessage(lp->ListBoxControl,LB_GETITEMHEIGHT, |
wParam,lParam); |
|
case CB_GETLBTEXT: |
return SendMessage(lp->ListBoxControl,LB_GETTEXT, |
wParam,lParam); |
|
case CB_GETLBTEXTLEN: |
return SendMessage(lp->ListBoxControl,LB_GETTEXTLEN, |
wParam,lParam); |
|
case CB_INSERTSTRING: |
return SendMessage(lp->ListBoxControl,LB_INSERTSTRING, |
wParam,lParam); |
|
case CB_SETITEMDATA: |
return SendMessage(lp->ListBoxControl,LB_SETITEMDATA, |
wParam,lParam); |
|
/*********************************************/ |
/* messages specific to the edit control */ |
/*********************************************/ |
case CB_GETEDITSEL: |
return SendMessage(lp->EditControl,EM_GETSEL,0,0); |
|
case CB_LIMITTEXT: |
return SendMessage(lp->EditControl,EM_LIMITTEXT, |
wParam,lParam); |
|
case CB_SETEDITSEL: |
return SendMessage(lp->EditControl,EM_SETSEL, |
wParam,lParam); |
|
/*********************************************/ |
/* messages handled by the combobox */ |
/*********************************************/ |
case CB_GETDROPPEDCONTROLRECT: |
CopyRect((LPRECT)lParam,&lp->ListBoxRect); |
break; |
case CB_GETDROPPEDSTATE: |
return IS_SET(lp,CSF_CAPTUREACTIVE); |
|
case CB_GETEXTENDEDUI: |
return (LRESULT)lp->bExtended; |
|
case CB_RESETCONTENT: |
SendMessage(lp->ListBoxControl,LB_RESETCONTENT,0,0); |
if (lp->EditControl) |
SendMessage(lp->EditControl,WM_SETTEXT,0,(LPARAM)(LPSTR)""); |
break; |
|
case CB_SELECTSTRING: |
index = (int)SendMessage(lp->ListBoxControl, LB_SELECTSTRING, wParam, lParam); |
if (index == LB_ERR) |
return CB_ERR; |
|
len = (int)SendMessage(lp->ListBoxControl, LB_GETTEXTLEN, index, 0); |
if (len <= 0) |
return CB_ERR; |
|
selection = (LPSTR)WinMalloc((UINT)len+1); |
rc = (int)SendMessage(lp->ListBoxControl, LB_GETTEXT, (WPARAM)index, (LPARAM)selection); |
if (lp->EditControl) |
rc = (int)SendMessage(lp->EditControl, WM_SETTEXT, 0, (LPARAM)selection); |
else CBoxDrawStatic(lp, hWnd, index); |
WinFree(selection); |
break; |
|
case CB_SETCURSEL: |
rc = (int)SendMessage(lp->ListBoxControl, LB_SETCURSEL, wParam, lParam); |
if (rc == LB_ERR) |
return CB_ERR; |
len = (int)SendMessage(lp->ListBoxControl, LB_GETTEXTLEN, wParam, 0); |
if (len <= 0) |
return CB_ERR; |
|
selection = (LPSTR)WinMalloc((UINT)len+1); |
rc = (int)SendMessage(lp->ListBoxControl, LB_GETTEXT, wParam, (LPARAM)selection); |
if (lp->EditControl) |
rc = (int)SendMessage(lp->EditControl, WM_SETTEXT, 0, (LPARAM)selection); |
else CBoxDrawStatic(lp, hWnd, wParam); |
WinFree(selection); |
return (LRESULT)wParam; |
|
case CB_SETEXTENDEDUI: |
lp->bExtended = (BOOL)wParam; |
break; |
|
case CB_SETITEMHEIGHT: /* TODO */ |
break; |
|
case CB_SHOWDROPDOWN: |
if ((lp->wStyle & 0xf) == CBS_SIMPLE) |
return 1L; |
if (wParam) |
{ |
if (IS_SET(lp,CSF_CAPTUREACTIVE)) |
return 1L; |
|
cp.x = ((lp->wStyle & 0xf) != CBS_DROPDOWNLIST) ? 5 : 0; |
cp.y = lp->uHeight -1; |
|
ClientToScreen(hWnd, &cp); |
OffsetRect(&lp->ListBoxRect, cp.x - lp->ListBoxRect.left, cp.y - lp->ListBoxRect.top); |
|
SetWindowPos(lp->ListBoxControl, 0, |
cp.x, cp.y, 0, 0, |
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); |
|
SendMessage(lp->hWndParent,WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID,hWnd,CBN_DROPDOWN)); |
|
fprintf(stderr," 1330: SetWindowPos(lp->ListBoxControl, , 0, 0, 0, 0,..)\n"); |
|
SetWindowPos(lp->ListBoxControl, HWND_TOP, |
0, 0, 0, 0, |
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW); |
|
CBoxCapture(hWnd, 1); |
SET_STATE(lp,CSF_CAPTUREACTIVE); |
} |
else |
{ |
if (!IS_SET(lp,CSF_CAPTUREACTIVE)) |
return 1L; |
|
SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID,hWnd,CBN_CLOSEUP)); |
/* test: */ |
fprintf(stderr," 1343: (hide) SetWindowPos(lp->ListBoxControl, , 0, 0, 0, 0,..)\n"); |
|
SetWindowPos(lp->ListBoxControl, 0, |
0, 0, 0, 0, |
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_HIDEWINDOW); |
|
CBoxCapture(hWnd, 0); |
CLEAR_STATE(lp, CSF_CAPTUREACTIVE); |
} |
return 1L; |
|
/*********************************************/ |
/* messages handled by the defwindowproc.... */ |
/*********************************************/ |
default: |
return DefWindowProc( hWnd, uMsg, wParam, lParam); |
} |
return CB_OKAY; |
} |
|
|
static void |
CBoxDrawButton(HWND hWnd,UINT wState,COMBOBOX *lp) |
{ |
HDC hDC; |
int x,y; |
int dx,dy; |
#if 0 /* jmt: fix: no LoadBitmap() */ |
int cx,cy; |
static int nWidth,nHeight; |
BITMAP bmpCombo; |
static HBITMAP hbmpCombo = 0; |
HBITMAP hbmpOld = 0; |
HDC hdcSrc; |
COLORREF rgbText, rgbBk; |
#endif |
HBRUSH hBrush; |
HPEN hPenHigh,hPenShadow; |
RECT rc; |
|
hDC = GetDC(hWnd); |
|
CopyRect(&rc,&lp->ButtonRect); |
x = rc.left; |
y = rc.top; |
dx = rc.right; |
dy = rc.bottom; |
|
hPenHigh = GetStockObject(WHITE_PEN); |
#if 0 |
hPenShadow = GetSysColorPen(COLOR_BTNSHADOW); |
#else |
hPenShadow = CreatePen(PS_SOLID,1,GetSysColor(COLOR_BTNSHADOW)); |
#endif |
#if 0 |
hBrush = GetSysColorBrush(COLOR_BTNFACE); |
#else |
hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); |
#endif |
FillRect(hDC, &rc, hBrush); |
#if 0 |
hBrush = GetStockObject(BLACK_BRUSH); |
FillRect/*FrameRect*/(hDC, &lp->ButtonRect, hBrush); |
#else |
SelectObject(hDC,GetStockObject(BLACK_PEN)); |
Rectangle(hDC,lp->ButtonRect.left,lp->ButtonRect.top,lp->ButtonRect.right,lp->ButtonRect.bottom); |
#endif |
rc.left += 1; rc.right -= 1; |
rc.top += 1; rc.bottom -= 1; |
|
Draw3DButtonRect(hDC,hPenHigh,hPenShadow,rc,wState); |
|
#if 0 /* jmt: fix: no LoadBitmap(),GetObject() */ |
if (hbmpCombo == 0) |
{ |
hbmpCombo = LoadBitmap(0,(LPSTR)OBM_COMBO); |
GetObject(hbmpCombo, sizeof(BITMAP), (LPVOID)&bmpCombo); |
nWidth = bmpCombo.bmWidth; |
nHeight = bmpCombo.bmHeight; |
} |
/* |
** MiD 08/15/95 changed to mono bitmap as it is in Windows. Convert |
** it to colors on the fly |
*/ |
hdcSrc = CreateCompatibleDC(hDC); |
hbmpOld = SelectObject(hdcSrc, hbmpCombo); |
/* |
** Source hdc ok. Prepare the target hdc, then BitBlt to it. |
*/ |
rgbText = SetTextColor(hDC,GetSysColor(COLOR_BTNTEXT)); |
rgbBk = SetBkColor(hDC,GetSysColor(COLOR_BTNFACE)); |
|
cx = (dx - x - nWidth)/2; |
cy = (dy - y - nHeight)/2; |
if (wState) |
{ cx++; cy++; } |
BitBlt(hDC, x+cx, y+cy, nWidth, nHeight, hdcSrc, 0, 0, SRCCOPY); |
|
SetTextColor(hDC, rgbText); |
SetBkColor(hDC, rgbBk); |
SelectObject(hdcSrc,hbmpOld); |
DeleteDC(hdcSrc); |
#endif /* BitBlt Bitmap */ |
#if 1 |
DeleteObject(hBrush); |
DeleteObject(hPenShadow); |
#endif |
ReleaseDC(hWnd,hDC); |
|
if (wState) |
SET_STATE(lp,CSF_LOCALBUTTONDOWN); |
else |
CLEAR_STATE(lp,CSF_LOCALBUTTONDOWN); |
} |
|
#if 0 /* jmt: fix: no COMBOLBOX */ |
/************************************************************************ |
** |
************************************************************************/ |
LRESULT DefCOMBOLBOXProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
{ |
#if 0 |
return DefLISTBOXProc(hWnd, msg, wParam,lParam); |
#endif |
return ListboxCtrlProc(hWnd, msg, wParam,lParam); |
} |
#endif |
|
/************************************************************************ |
** |
************************************************************************/ |
static void CBoxSendMouseToLBox(COMBOBOX *lp, UINT uiMsg, WPARAM wParam, POINT ptScreen) |
{ |
POINT pt; |
int nNCHit; |
#if 0 /* jmt: fix: no scrollbar */ |
HWND hWndScroll; |
#endif |
pt = ptScreen; |
ScreenToClient(lp->ListBoxControl,&pt); |
|
nNCHit = LOSHORT(SendMessage(lp->ListBoxControl, WM_NCHITTEST, 0, MAKELPARAM(ptScreen.x,ptScreen.y))); |
|
switch (nNCHit) |
{ |
case HTCLIENT: |
if (uiMsg == WM_MOUSEMOVE && !IS_SET(lp,CSF_LBOXBUTTONDOWN)) |
{ |
SendMessage(lp->ListBoxControl, WM_LBUTTONDOWN, 0, MAKELONG((WORD)pt.x,(WORD)pt.y)); |
|
SET_STATE(lp, CSF_BUTTONDOWN | CSF_LBOXBUTTONDOWN); |
} |
SendMessage(lp->ListBoxControl, uiMsg, wParam, MAKELONG((WORD)pt.x,(WORD)pt.y)); |
break; |
|
#if 0 /* jmt: fix: no scrollbar */ |
case HTVSCROLL: |
if (0 != (hWndScroll = TWIN_ConvertToSysScroll(lp->ListBoxControl, TRUE /* vertical */, &pt))) |
SendMessage(hWndScroll, uiMsg, wParam, MAKELONG((WORD)pt.x,(WORD)pt.y)); |
break; |
#endif |
default: |
break; |
} |
} |
|
/************************************************************************ |
** |
************************************************************************/ |
static void CBoxCapture(HWND hWnd, WORD wFunc) |
{ |
static HWND hWndCapture = (HWND)0; |
|
if (wFunc) |
{ |
hWndCapture = SetCapture(hWnd); |
|
SetFocus(hWnd); |
} |
else { |
if (!hWndCapture) |
ReleaseCapture(); |
else { |
#ifdef LATER |
SetCapture(hWndCapture); |
#else |
ReleaseCapture(); |
#endif |
hWndCapture = (HWND)0; |
} |
} |
} |
|
/************************************************************************ |
** |
************************************************************************/ |
static void CBoxDrawEdit(COMBOBOX *lp, HWND hWnd, UINT uiKey) |
{ |
int nLen; |
LPVOID lpData; |
#if 0 /* jmt: fix: no ownerdraw */ |
HRGN hRgn; |
DRAWITEMSTRUCT dis; |
#endif |
/* |
if (uiKey == (UINT)LB_ERR) |
return; |
|
if (!BOWNERDRAW(lp)) |
*/ |
if (lp->wStyle & CBS_HASSTRINGS) |
{ |
if (uiKey == (UINT)LB_ERR) |
return; |
nLen = (int)SendMessage(lp->ListBoxControl, LB_GETTEXTLEN, uiKey, 0L); |
if (nLen <= 0) |
return; |
lpData = (LPVOID)WinMalloc(nLen+1); |
SendMessage(lp->ListBoxControl, LB_GETTEXT, uiKey, (LPARAM)lpData); |
SendMessage(lp->EditControl, WM_SETTEXT, strlen(lpData), (LPARAM)lpData); |
Edit_SetSel(lp->EditControl, 0, -1); |
WinFree((LPSTR)lpData); |
} |
#if 0 /* jmt: fix: no ownerdraw */ |
else { |
dis.CtlType = ODT_COMBOBOX; |
dis.CtlID = (UINT)lp->nID; |
dis.itemID = -1; /* used to be uiKey */ |
dis.itemAction = ODA_DRAWENTIRE; |
dis.itemState = ODS_FOCUS; |
dis.hwndItem = hWnd; |
dis.itemData = 0; |
GetClientRect(lp->EditControl,&dis.rcItem); |
dis.rcItem.left += 3; |
dis.rcItem.right -= 3; |
dis.rcItem.top += 2; |
dis.rcItem.bottom -= 2; |
|
dis.hDC = GetDC(lp->EditControl); |
hRgn = CreateRectRgnIndirect(&dis.rcItem); |
SelectClipRgn(dis.hDC,hRgn); |
SelectObject(dis.hDC, lp->hFont); |
SendMessage(lp->hWndParent, WM_DRAWITEM, (WPARAM)(UINT)lp->nID, (LPARAM)&dis); |
ReleaseDC(lp->EditControl,dis.hDC); |
DeleteObject(hRgn); |
} |
#endif /* ownerdraw */ |
} |
|
/************************************************************************ |
** |
************************************************************************/ |
static void CBoxDrawStatic(COMBOBOX *lp, HWND hWnd, UINT uiKey) |
{ |
int nLen; |
HDC hdc; |
LPVOID lpData; |
RECT rcClient; |
HFONT hfonOld = 0; |
#if 0 /* jmt: fix: no ownerdraw */ |
HRGN hRgn; |
DRAWITEMSTRUCT dis; |
#endif |
HBRUSH hbrStatic, hbrOld; |
|
/* Draw rectangle regardless of ownerdraw style... |
*/ |
hdc = GetDC(hWnd); |
rcClient.left = 0; |
rcClient.top = 0; |
rcClient.right = lp->ButtonRect.left+1; |
rcClient.bottom = lp->uHeight; |
hbrStatic = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); |
hbrOld = SelectObject(hdc, hbrStatic); |
SelectObject(hdc, GetStockObject(BLACK_PEN));/* ??? COLOR_WINDOWFRAME */ |
Rectangle(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); |
SelectObject(hdc, hbrOld); |
DeleteObject(hbrStatic); |
ReleaseDC(hWnd, hdc); |
|
if (uiKey == (UINT)LB_ERR) |
return; |
|
/* jmt: no ownerdraw */ |
if (1) /* (!BOWNERDRAW(lp)) */ |
{ |
/* if necessary, draw text */ |
hdc = GetDC(hWnd); |
nLen = (int)SendMessage(lp->ListBoxControl, LB_GETTEXTLEN, (WPARAM)uiKey, 0L); |
if (nLen > 0) |
{ |
lpData = (LPVOID)WinMalloc(nLen+1); |
SendMessage(lp->ListBoxControl, LB_GETTEXT, uiKey, (LPARAM)lpData); |
SetBkMode(hdc, TRANSPARENT); |
if (!IS_SET(lp, CSF_FOCUS)) |
{ |
SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT)); |
rcClient.left += 2; |
} |
else { |
InflateRect(&rcClient, -2, -2); |
hbrStatic = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); |
hbrOld = SelectObject(hdc, hbrStatic); |
FillRect(hdc, &rcClient, hbrStatic); |
#if 0 /* jmt: fix: no DrawFocusRect() */ |
DrawFocusRect(hdc, &rcClient); |
#endif |
SelectObject(hdc, hbrOld); |
DeleteObject(hbrStatic); |
SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); |
} |
if (lp->hFont) |
hfonOld = SelectObject(hdc, lp->hFont); |
DrawText(hdc, (LPSTR)lpData, nLen, &rcClient, DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX); |
if (lp->hFont) |
SelectObject(hdc, hfonOld); |
WinFree((LPVOID)lpData); |
} |
ReleaseDC(hWnd, hdc); |
} |
#if 0 /* jmt: fix: no ownerdraw */ |
else { /* fill OWNERDRAWSTRUCT and send WM_DRAWITEM message */ |
dis.CtlType = ODT_COMBOBOX; |
dis.CtlID = (UINT)lp->nID; |
dis.itemID = uiKey; |
dis.itemAction = ODA_DRAWENTIRE; |
dis.itemState = ODS_FOCUS; |
dis.hwndItem = hWnd; |
dis.itemData = SendMessage(lp->ListBoxControl, LB_GETITEMDATA, uiKey, 0L); |
GetClientRect(hWnd, &dis.rcItem); |
dis.rcItem.left += 3; |
dis.rcItem.right = lp->ButtonRect.left - 2; /* do not touch button */ |
dis.rcItem.top += 2; |
dis.rcItem.bottom -= 2; |
|
dis.hDC = GetDC(hWnd); |
hRgn = CreateRectRgnIndirect(&dis.rcItem); |
SelectClipRgn(dis.hDC, hRgn); |
SelectObject(dis.hDC, lp->hFont); |
SendMessage(lp->hWndParent, WM_DRAWITEM, (WPARAM)(UINT)lp->nID, (LPARAM)&dis); |
ReleaseDC(hWnd, dis.hDC); |
DeleteObject(hRgn); |
} |
#endif /* ownerdraw */ |
|
} |
|
|
/*------------------------- < Full Revision History > ---------------------- |
** Revision 1.2 2001/11/06 23:35:46 greg |
** |
** Revision 1.1.1.1 2001/06/21 06:32:42 greg |
** Microwindows pre8 with patches |
** |
** Revision 1.1.1.1 2001/06/05 03:44:01 root |
** First import of 5/5/2001 Microwindows to CVS |
** |
** Revision 1.8 2000/08/14 jmt |
** ported to microwin(non-client/server mode) |
** |
** Revision 1.7 2000/06/28 jmt |
** porting to microwin |
** |
** Revision 1.6 2000/01/21 02:48:47 robf |
** remove dead code |
** |
** Revision 1.5 1999/11/29 05:07:54 robf |
** removed extraneous call CreateCompatibleDC |
** |
** Revision 1.4 1999/07/08 18:52:50 mwalsh |
** Updated Comments |
** |
**-------------------------------------------------------------------------*/ |
|
/ptinsid.c
0,0 → 1,18
#include "windows.h" |
#include "wintools.h" |
|
BOOL WINAPI |
PtInsideWindow(HWND hwnd,UINT x,UINT y) |
{ |
/* Determine whether or not the position ( x, y) is contained */ |
/* within the control's client rectangle. */ |
|
RECT clientRect; |
POINT buttonPoint; |
|
buttonPoint.x = x; |
buttonPoint.y = y; |
|
GetClientRect( hwnd, &clientRect); |
return PtInRect( &clientRect, buttonPoint); |
} |
/button.c
0,0 → 1,898
#include "windows.h" |
#include "windowsx.h" |
#include "wintools.h" |
/* |
* WINCTL Custom Control Library |
* Push button Custom Control |
* This control implements a custom pushbutton control. |
* |
* 4/8/98 g haerr original version from control palette v2.00, Blaise Computing |
*/ |
|
#define GET_PBSTATE(h) (GetWindowWord(h, 0)) |
#define GET_PBCAPTURE(h) (GetWindowWord(h, 2)) |
#define GET_PBWASINSIDE(h) (GetWindowWord(h, 4)) |
#define GET_PBDELETEFONT(h) (GetWindowWord(h, 6)) |
#define GET_PBFONT(h) (GetWindowWord(h, 8)) |
|
#define SET_PBSTATE(h,x) (SetWindowWord(h, 0, x)) |
#define SET_PBCAPTURE(h,x) (SetWindowWord(h, 2, x)) |
#define SET_PBWASINSIDE(h,x) (SetWindowWord(h, 4, x)) |
#define SET_PBDELETEFONT(h,x) (SetWindowWord(h, 6, x)) |
#define SET_PBFONT(h,x) (SetWindowWord(h, 8, x)) |
|
#define PARENT(hwnd) ((HWND)GetWindowLong(hwnd,GWL_HWNDPARENT)) |
|
/* Internal state variable bit positions */ |
#define PUSH_UP 0x0000 |
#define PUSH_DOWN 0x0001 /* Button is down */ |
#define PUSH_FOCUS 0x0002 /* Button is focused */ |
#define PUSH_DISABLED 0x0004 /* Button is disabled */ |
#define PUSH_DEFAULT 0x0008 /* Button is currently a default */ |
#define PUSH_CHECKED 0x0010 |
|
/* Push Button states */ |
#define PBS_UP 0x0000 /* Normal button state. */ |
#define PBS_FOCUSDOWN 0x0001 /* Button pressed. */ |
#define PBS_FOCUSUP 0x0002 /* Focused state. */ |
#define PBS_DISABLED 0x0004 /* Disabled state. */ |
#define PBS_DEFAULT 0x0008 /* Default state. */ |
#define PBS_CHECKED 0x0010 /* checked state. */ |
|
#define WM_PAINT_SPECIAL WM_PAINT |
#define HANDLE_WM_PAINT_SPECIAL(hwnd, wParam, lParam, fn) \ |
((fn)((hwnd),(HDC)(wParam)), 0L) |
|
/* BOOL Cls_OnGetState( HWND hwnd); */ |
#define HANDLE_BM_GETSTATE(hwnd, wParam, lParam, fn) ((fn)(hwnd)) |
#define FORWARD_BM_GETSTATE(hwnd) \ |
(LONG)(fn)((hwnd), BM_GETSTATE, (WPARAM)0, (LPARAM)0) |
|
/* void Cls_OnSetState( HWND hwnd, WORD wState); */ |
#define HANDLE_BM_SETSTATE( hwnd, wParam, lParam, fn) \ |
((fn)((hwnd), (WORD)wParam), 0) |
#define FORWARD_BM_SETSTATE( hwnd, wState) \ |
(fn)((hwnd), BM_SETSTATE, (WPARAM)wState, (LPARAM)0) |
|
/* void Cls_OnSetStyle( HWND hwnd, WORD style, BOOL bRedraw); */ |
#define HANDLE_BM_SETSTYLE( hwnd, wParam, lParam, fn) \ |
((fn)((hwnd), (WORD)wParam, (BOOL)LOWORD(lParam)), 0) |
#define FORWARD_BM_SETSTYLE( hwnd, style, bRedraw, fn) \ |
(fn)((hwnd), BM_SETSTYLE, (WPARAM)style, MAKELPARAM(bRedraw, 0)) |
|
/* entry points*/ |
void WINAPI CheckRadioButton(HWND hDlg, int nIDFirst,int nIDLast, |
int nIDCheckButton); |
|
/* local procs*/ |
static void WINAPI cenButton_FnEnd( HWND, WORD); |
static WORD WINAPI cenButton_FnStart( HWND); |
static BOOL WINAPI cenButton_OnCreate( HWND, LPCREATESTRUCT); |
/*static void WINAPI cenButton_OnDestroy( HWND);*/ |
/*static void WINAPI cenButton_OnEnable( HWND, BOOL);*/ |
static BOOL WINAPI cenButton_OnEraseBkgnd( HWND, HDC); |
/*static UINT WINAPI cenButton_OnGetDlgCode( HWND, LPMSG);*/ |
static LONG WINAPI cenButton_OnGetState( HWND); |
/*static void WINAPI cenButton_OnKey( HWND, UINT, BOOL, int, UINT);*/ |
static void WINAPI cenButton_OnKillFocus( HWND, HWND); |
static void WINAPI cenButton_OnLButtonDown( HWND, BOOL, UINT, UINT, UINT); |
static void WINAPI cenButton_OnLButtonUp( HWND, UINT, UINT, UINT); |
static void WINAPI cenButton_OnMouseMove( HWND, UINT, UINT, UINT); |
static void WINAPI cenButton_OnPaint( HWND, HDC); |
static void WINAPI DrawPushButton(HWND hwnd,HDC hDCwParam,UINT wEnumState, |
DWORD dwStyle); |
static void WINAPI DrawGroupBox(HWND hwnd,HDC hDCwParam, DWORD dwStyle); |
static void WINAPI cenButton_OnSetFocus( HWND, HWND); |
static void WINAPI cenButton_OnSetStyle( HWND, WORD, BOOL); |
static void WINAPI cenButton_OnSetState( HWND, WORD); |
static void WINAPI cenButton_SetState( HWND, WORD, BOOL); |
static void WINAPI cenButton_OnSetText( HWND, LPCSTR); |
|
static void WINAPI |
cenButton_FnEnd( |
HWND hwnd, |
WORD wState) |
{ |
if( wState != GET_PBSTATE( hwnd)) { |
if( IsWindowVisible( hwnd)) |
UpdateWindow( hwnd); |
} |
} |
|
static WORD WINAPI |
cenButton_FnStart( |
HWND hwnd) |
{ |
return GET_PBSTATE( hwnd); |
} |
|
static BOOL WINAPI |
cenButton_OnCreate( |
HWND hwnd, |
LPCREATESTRUCT lpCreate) |
{ |
/* Set initial states */ |
/*SET_PBDELETEFONT( hwnd, FALSE);*/ |
/*SET_PBFONT( hwnd, NULL);*/ |
SET_PBSTATE( hwnd, PUSH_UP ); |
SET_PBCAPTURE( hwnd, FALSE ); |
SET_PBWASINSIDE( hwnd, FALSE ); |
|
if ((lpCreate->style & 0x0f) == BS_DEFPUSHBUTTON) |
cenButton_SetState( hwnd, PUSH_DEFAULT, TRUE ); |
|
if (lpCreate->style & WS_DISABLED) |
cenButton_SetState( hwnd, PUSH_DISABLED, TRUE ); |
|
return( TRUE); |
} |
|
#if 0 |
static void WINAPI |
cenButton_OnDestroy( |
HWND hwnd) |
{ |
if( GET_PBDELETEFONT( hwnd)) { |
DeleteObject( GET_PBFONT( hwnd)); |
SET_PBDELETEFONT( hwnd, FALSE); |
} |
} |
|
static void WINAPI |
cenButton_OnEnable( |
HWND hwnd, |
BOOL bEnable) |
{ |
WORD wState; |
|
wState = cenButton_FnStart( hwnd); |
cenButton_SetState( hwnd, PUSH_DISABLED, !bEnable); |
cenButton_FnEnd( hwnd, wState); |
} |
#endif |
|
static BOOL WINAPI |
cenButton_OnEraseBkgnd( |
HWND hwnd, |
HDC hdc) |
{ |
/* Background is erased at WM_PAINT time, so return TRUE*/ |
return TRUE; |
} |
|
#if 0 |
static UINT WINAPI |
cenButton_OnGetDlgCode( |
HWND hwnd, |
LPMSG lpMsg) |
{ |
/* WM_GETDLGCODE is sent by the dialog manager to find */ |
/* what type/style of control is responding and/or to */ |
/* determine what keystrokes the control wants to process */ |
/* itself. In this case, the pushbutton identifies itself */ |
/* and also indicates whether it is currently the default */ |
/* pushbutton. */ |
|
/*return( DLGC_BUTTON | ((GET_PBSTATE( hwnd) & PUSH_DEFAULT) ? |
DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON));*/ |
return( DLGC_BUTTON); |
} |
#endif |
|
static LONG WINAPI |
cenButton_OnGetState( |
HWND hwnd) |
{ |
/* BM_GETSTATE is sent to enquire about the state of the */ |
/* control. It returns TRUE if the button is in the down */ |
/* state. */ |
|
return( ( GET_PBSTATE( hwnd) & PUSH_DOWN) == PUSH_DOWN); |
} |
|
#if 0 |
static void WINAPI |
cenButton_OnKey( |
HWND hwnd, |
UINT vk, |
BOOL bDown, |
int cRepeat, |
UINT flag) |
{ |
WORD wState; |
|
wState = cenButton_FnStart( hwnd); |
if (bDown) { |
/* WM_KEYDOWN is sent when a non-system key is pressed. */ |
/* If a spacebar is detected and the previous key state */ |
/* was up, then the control should switch to the down */ |
/* state. */ |
|
if ( (vk == ' ') && !(HIBYTE(flag) & 0x40) ) |
cenButton_SetState( hwnd, PUSH_DOWN, TRUE ); |
} |
else { |
/* WM_KEYUP is sent when a non-system key is released. */ |
/* If a space bar is detected, change to the up state. If */ |
/* the control is the focused control, send the BN_CLICKED */ |
/* notification message. */ |
|
if ( vk == ' ' ) |
{ cenButton_SetState( hwnd, PUSH_DOWN, FALSE ); |
|
if (GET_PBSTATE( hwnd) & PUSH_FOCUS) { |
FORWARD_WM_COMMAND( PARENT( hwnd), GetDlgCtrlID( hwnd), |
hwnd, BN_CLICKED, SendMessage); |
if(!IsWindow(hwnd)) |
return; |
} |
} |
} |
cenButton_FnEnd( hwnd, wState); |
} |
#endif |
|
static void WINAPI |
cenButton_OnKillFocus( |
HWND hwnd, |
HWND hwndNewFocus) |
{ |
WORD wState; |
|
wState = cenButton_FnStart( hwnd); |
cenButton_SetState( hwnd, PUSH_FOCUS, FALSE ); |
cenButton_FnEnd( hwnd, wState); |
} |
|
static void WINAPI |
cenButton_OnLButtonDown( |
HWND hwnd, |
BOOL bDblClick, |
UINT x, |
UINT y, |
UINT keyState) |
{ |
WORD wState; |
|
wState = cenButton_FnStart( hwnd); |
/* capture the mouse*/ |
SetCapture( hwnd ); |
/* set focus to ourself*/ |
SetFocus( hwnd ); |
SET_PBCAPTURE( hwnd, TRUE ); |
SET_PBWASINSIDE( hwnd, TRUE ); |
/* set down state*/ |
cenButton_SetState( hwnd, PUSH_DOWN, TRUE ); |
cenButton_FnEnd( hwnd, wState); |
} |
|
static void WINAPI |
cenButton_OnLButtonUp( |
HWND hwnd, |
UINT x, |
UINT y, |
UINT keys) |
{ |
WORD wState; |
DWORD dwStyle; |
|
dwStyle = GetWindowLong(hwnd, GWL_STYLE); |
wState = cenButton_FnStart( hwnd); |
|
/* only draw up state if we captured mouse*/ |
if(GetCapture() == hwnd) |
cenButton_SetState( hwnd, PUSH_DOWN, FALSE ); |
/* release mouse capture*/ |
ReleaseCapture(); |
|
/* if cursor is inside control, send clicked notification to parent*/ |
if (GET_PBWASINSIDE( hwnd)) { |
switch((int)(dwStyle & 0x0f)) { |
case BS_AUTOCHECKBOX: |
SendMessage(hwnd,BM_SETCHECK,(wState & PBS_CHECKED)?0:1,0L); |
break; |
case BS_AUTORADIOBUTTON: |
CheckRadioButton(PARENT(hwnd),0,0xffff,hwnd->id); |
break; |
} |
FORWARD_WM_COMMAND( PARENT( hwnd), GetDlgCtrlID( hwnd), hwnd, |
BN_CLICKED, SendMessage); |
if(!IsWindow(hwnd)) |
return; |
} |
|
SET_PBCAPTURE( hwnd, FALSE ); |
SET_PBWASINSIDE( hwnd, FALSE ); |
cenButton_FnEnd( hwnd, wState); |
} |
|
static void WINAPI |
cenButton_OnMouseMove( |
HWND hwnd, |
UINT x, |
UINT y, |
UINT keys) |
{ |
/* WM_MOUSEMOVE is sent at every discernable mouse */ |
/* movement. It is necessary to detect this because if */ |
/* the mouse has been captured (because of a button down */ |
/* message), the location of the cursor needs to be */ |
/* tracked. If it moves out of the confines of the */ |
/* control, the control should change to the focus/up */ |
/* state (and retain capture.) If the cursor then moves */ |
/* back into the control, change back to the down state. */ |
|
WORD wState; |
DWORD dwStyle; |
|
wState = cenButton_FnStart( hwnd); |
dwStyle = GetWindowLong(hwnd, GWL_STYLE); |
if( GET_PBCAPTURE( hwnd)) { |
if( !PtInsideWindow( hwnd, x, y) ) { |
if( GET_PBWASINSIDE( hwnd)) { |
cenButton_SetState( hwnd, PUSH_DOWN, FALSE); |
SET_PBWASINSIDE( hwnd, FALSE ); |
} |
} else { |
if( !GET_PBWASINSIDE( hwnd) ) { |
cenButton_SetState( hwnd, PUSH_DOWN, TRUE ); |
SET_PBWASINSIDE( hwnd, TRUE ); |
} |
} |
} |
cenButton_FnEnd( hwnd, wState); |
} |
|
static void WINAPI |
cenButton_OnPaint( |
HWND hwnd, |
HDC hDCwParam) |
{ |
UINT wEnumState; |
DWORD dwStyle; |
|
if( GET_PBSTATE( hwnd) & PUSH_DISABLED) |
wEnumState = PBS_DISABLED; |
else if( GET_PBSTATE( hwnd) & PUSH_DOWN) |
wEnumState = PBS_FOCUSDOWN; |
else if( GET_PBSTATE( hwnd) & PUSH_CHECKED) |
wEnumState = PBS_CHECKED; |
else |
{ |
if( GET_PBSTATE( hwnd) & PUSH_FOCUS) |
wEnumState = PBS_FOCUSUP; |
else |
wEnumState = PBS_UP; |
if( GET_PBSTATE( hwnd) & PUSH_DEFAULT) |
wEnumState |= PBS_DEFAULT; |
} |
|
/* common draw code for button and checkbox*/ |
dwStyle = GetWindowLong(hwnd, GWL_STYLE); |
switch((int)(dwStyle & 0x0f)) { |
case BS_GROUPBOX: |
DrawGroupBox( hwnd, hDCwParam, dwStyle); |
break; |
default: |
DrawPushButton( hwnd, hDCwParam, wEnumState, dwStyle); |
} |
} |
|
static void WINAPI |
DrawPushButton(HWND hwnd,HDC hDCwParam,UINT wEnumState,DWORD dwStyle) |
{ |
HDC hdc; |
HBRUSH hNewBrush; |
RECT rect; |
RECT rectClient; |
RECT rectSave; |
RECT rc; |
int iFaceOffset = 0; |
INT uiHeight; |
INT uiWidth; |
COLORREF crOld; |
COLORREF crBkOld; |
int oldBkMode; |
HFONT hNewFont; |
HFONT hOldFont; |
HPEN hOldPen; |
COLORREF hOldColor; |
PAINTSTRUCT ps; |
char buf[256]; |
#define uiWidthFrame 0 |
#define uiWidthShadow 2 |
|
hdc = BeginPaint(hwnd, &ps); |
if(!hdc) |
goto Return; |
|
GetWindowText(hwnd, buf, sizeof(buf)); |
GetClientRect( hwnd, &rectClient ); |
uiWidth = rectClient.right - rectClient.left; |
uiHeight = rectClient.bottom - rectClient.top; |
|
hNewBrush = (HBRUSH) GetStockObject(LTGRAY_BRUSH); |
crOld = SetTextColor( hdc, GetSysColor( COLOR_BTNTEXT)); |
crBkOld = SetBkColor( hdc, GetSysColor( COLOR_BTNFACE)); |
|
rc = rectClient; |
switch((int)(dwStyle & 0x0f)) { |
case BS_PUSHBUTTON: |
case BS_DEFPUSHBUTTON: |
if( wEnumState & PBS_FOCUSDOWN) { |
Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, |
GetSysColor(COLOR_WINDOWFRAME), GetSysColor(COLOR_WINDOWFRAME)); |
InsetR(&rc, 1, 1); |
Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, |
GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNSHADOW)); |
InsetR(&rc, 1, 1); |
FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNFACE)); |
iFaceOffset = 1; |
} else { |
if(wEnumState & PBS_DEFAULT) { |
Draw3dBox(hdc, rc.left, rc.top, |
rc.right-rc.left, rc.bottom-rc.top, |
GetSysColor(COLOR_WINDOWFRAME), |
GetSysColor(COLOR_WINDOWFRAME)); |
InsetR(&rc, 1, 1); |
} |
Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, |
GetSysColor(COLOR_BTNHIGHLIGHT),GetSysColor(COLOR_WINDOWFRAME)); |
InsetR(&rc, 1, 1); |
Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, |
GetSysColor(COLOR_3DLIGHT), GetSysColor(COLOR_BTNSHADOW)); |
InsetR(&rc, 1, 1); |
FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNFACE)); |
iFaceOffset = 0; |
} |
break; |
|
case BS_CHECKBOX: |
case BS_AUTOCHECKBOX: |
FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNFACE)); |
/*rc.left += 2;*/ |
/*rc.top += 2;*/ |
rc.right = rc.left + 12; |
rc.bottom = rc.top + 12; |
/*Draw3dBox(hdc, rc.left, rc.top, 8, 8, |
GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_3DLIGHT));*/ |
Draw3dInset(hdc, rc.left, rc.top, 12, 12); |
InsetR(&rc, 2, 2); |
FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNHIGHLIGHT)); |
iFaceOffset = 1; |
if(wEnumState & PBS_CHECKED) { |
MoveToEx(hdc, rc.left, rc.top,NULL); |
LineTo(hdc, rc.right, rc.bottom); |
MoveToEx(hdc, rc.left, rc.bottom,NULL); |
LineTo(hdc, rc.right, rc.top); |
} |
break; |
|
case BS_AUTORADIOBUTTON: |
case BS_RADIOBUTTON: |
FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNFACE)); |
rc.left = 0; |
rc.top += 1; |
rc.right = rc.left + 10; |
rc.bottom = rc.top + 10; |
|
SelectObject(hdc, GetStockObject(NULL_BRUSH)); |
hOldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, |
GetSysColor(COLOR_BTNSHADOW))); |
SelectObject(hdc, GetStockObject(WHITE_BRUSH)); |
Ellipse(hdc,rc.left,rc.top, rc.right,rc.bottom); |
InsetR(&rc, 1, 1); |
|
SelectObject(hdc, GetStockObject(WHITE_BRUSH)); |
DeleteObject(SelectObject(hdc, |
CreatePen(PS_SOLID, 1,GetSysColor(COLOR_WINDOWFRAME)))); |
Ellipse(hdc,rc.left,rc.top, rc.right,rc.bottom); |
DeleteObject(SelectObject(hdc, hOldPen)); |
|
iFaceOffset = 0; |
if(wEnumState & PBS_CHECKED) |
Ellipse(hdc, rc.left+2, rc.top+2, rc.right-2, |
rc.bottom-2); |
break; |
} |
|
/* |
* draw text |
*/ |
if(buf[ 0]) { |
hNewFont = GetStockObject( DEFAULT_GUI_FONT); |
hOldFont = SelectObject( hdc, hNewFont); |
|
/* calculate text bounding rect*/ |
rect.left = 0; |
rect.top = 0; |
DrawText( hdc, buf, -1, &rect, DT_CALCRECT | DT_LEFT | |
DT_SINGLELINE | DT_TOP); |
rectSave = rect; |
|
/* |
* calculate text draw location |
*/ |
switch((int)(dwStyle & (BS_LEFT|BS_CENTER|BS_RIGHT))) { |
case BS_CENTER: |
default: |
rect.left = (uiWidth - (rect.right - rect.left)) / 2 |
+ iFaceOffset; |
break; |
case BS_LEFT: |
rect.left = uiWidthFrame + uiWidthShadow + 2 |
+ iFaceOffset; |
break; |
case BS_RIGHT: |
rect.left = (rect.right - rect.left) + uiWidthFrame |
+ uiWidthShadow + 4 + iFaceOffset; |
break; |
} |
|
switch((int)(dwStyle & 0x0f)) { |
case BS_CHECKBOX: |
case BS_AUTOCHECKBOX: |
case BS_AUTORADIOBUTTON: |
case BS_RADIOBUTTON: |
rect.left = 12; |
break; |
} |
|
rect.right += rect.left - rectSave.left; |
|
switch((int)(dwStyle & (BS_TOP|BS_VCENTER|BS_BOTTOM))) { |
case BS_VCENTER: |
default: |
rect.top = (uiHeight - (rect.bottom - rect.top)) / 2 |
+ iFaceOffset; |
break; |
case BS_TOP: |
rect.top = 2 + uiWidthFrame + uiWidthShadow |
+ iFaceOffset; |
break; |
case BS_BOTTOM: |
rect.top = uiHeight - uiWidthFrame - uiWidthShadow - |
(rect.bottom - rect.top) - 1 + iFaceOffset; |
break; |
} |
switch((int)(dwStyle & 0x0f)) { |
case BS_CHECKBOX: |
case BS_AUTOCHECKBOX: |
case BS_AUTORADIOBUTTON: |
case BS_RADIOBUTTON: |
rect.top = 0; |
break; |
} |
rect.bottom += rect.top - rectSave.top; |
|
oldBkMode = SetBkMode( hdc, TRANSPARENT); |
if(wEnumState & PBS_DISABLED) |
hOldColor = SetTextColor( hdc, |
GetSysColor( COLOR_GRAYTEXT)); |
else |
hOldColor = SetTextColor( hdc, |
GetSysColor( COLOR_BTNTEXT)); |
|
DrawText( hdc, buf, -1, &rect,DT_LEFT | DT_SINGLELINE | DT_TOP); |
|
SetBkMode( hdc, oldBkMode); |
SetTextColor( hdc, hOldColor); |
SelectObject( hdc, hOldFont); |
} |
|
#if 0 |
if( (!(wEnumState&PBS_CHECKED) && (wEnumState&PBS_FOCUSDOWN)) || |
(wEnumState & PBS_FOCUSUP)) { |
rect = rectClient; |
uiWidth = uiWidthFrame + uiWidthShadow + 2; |
rect.left += uiWidth; |
rect.top += uiWidth; |
rect.right -= uiWidth; |
rect.bottom -= uiWidth; |
if((dwStyle & (BS_FLAT|BS_NOFOCUSRECT)) == 0) |
DrawFocusRect( hdc, &rect); |
} |
#endif |
|
SetTextColor( hdc, crOld); |
SetBkColor( hdc, crBkOld); |
|
Return: |
EndPaint(hwnd, &ps); |
} |
|
static void WINAPI |
cenButton_OnSetFocus( |
HWND hwnd, |
HWND hwndOldFocus) |
{ |
/* WM_SETFOCUS is sent when the user clicks on the control */ |
/* or when the dialog manager determines that a keystroke */ |
/* should cause the control to be focused. This affects */ |
/* the appearance of the control so the state is saved for */ |
/* future drawing. */ |
|
WORD wState; |
|
wState = cenButton_FnStart( hwnd); |
/*if(!IsWindowEnabled(hwnd)) |
cenButton_SetState( hwnd, PUSH_FOCUS, TRUE );*/ |
cenButton_FnEnd( hwnd, wState); |
} |
|
static void WINAPI |
cenButton_OnSetStyle( |
HWND hwnd, |
WORD style, |
BOOL bRedraw) |
{ |
WORD wState; |
|
wState = cenButton_FnStart( hwnd); |
cenButton_SetState( hwnd, PUSH_DEFAULT, |
(style & 0x0f) == BS_DEFPUSHBUTTON); |
cenButton_FnEnd( hwnd, wState); |
} |
|
static void WINAPI |
cenButton_OnSetState( |
HWND hwnd, |
WORD wState) |
{ |
WORD wStateOld; |
|
wStateOld = cenButton_FnStart( hwnd); |
cenButton_SetState( hwnd, PUSH_DOWN, (wState ? TRUE : FALSE ) ); |
cenButton_FnEnd( hwnd, wStateOld); |
} |
|
static void WINAPI |
cenButton_SetState( |
HWND hwnd, |
WORD wState, |
BOOL bEnable ) |
{ |
/* Turn on/off state bits according to the bEnable flag. If the */ |
/* new state is different, invalidate the client window so that */ |
/* the proper bitmap is displayed. */ |
|
WORD wNewState; |
WORD wOldState; |
RECT rectClient; |
|
wOldState = GET_PBSTATE( hwnd); |
wNewState = (bEnable ? (wOldState | wState) : (wOldState & ~wState)); |
|
if (wOldState != wNewState) |
{ SET_PBSTATE( hwnd, wNewState ); |
GetClientRect(hwnd, &rectClient); |
InvalidateRect(hwnd, &rectClient, FALSE); |
} |
} |
|
#if 0 |
static void WINAPI |
cenButton_OnSetFont( |
HWND hwnd, |
HFONT hFont, |
BOOL bRedraw) |
{ |
BOOL bDeleteFont = FALSE; |
HFONT hFontNew = 0; |
LOGFONT logFont; |
|
/* create a thin font*/ |
if( GetObject( hFont, sizeof( logFont), &logFont) != 0) { |
if( logFont.lfWeight != FW_NORMAL) { |
logFont.lfWeight = FW_NORMAL; |
if( ( hFontNew = CreateFontIndirect( &logFont)) != 0) { |
hFont = hFontNew; |
bDeleteFont = TRUE; |
} |
} |
} |
|
if( GET_PBDELETEFONT( hwnd)) |
DeleteObject( GET_PBFONT( hwnd)); |
|
SET_PBDELETEFONT( hwnd, bDeleteFont); |
SET_PBFONT( hwnd, hFont); |
|
FORWARD_WM_SETFONT( hwnd, hFont, bRedraw, DefWindowProc); |
} |
#endif |
|
static void WINAPI |
cenButton_OnSetText( |
HWND hwnd, |
LPCSTR lpszText) |
{ |
/* WM_SETTEXT is sent to change the text of the button */ |
/* control. In this case we allow the default window proc */ |
/* to handle the message first. But this only affects the */ |
/* internal Windows data structure of the control, it does */ |
/* not display the change. To do this we invalidate and */ |
/* update the client area of the control which displays */ |
/* the new text. */ |
|
FORWARD_WM_SETTEXT( hwnd, lpszText, DefWindowProc); |
InvalidateRect( hwnd, NULL, FALSE); |
UpdateWindow( hwnd); |
} |
|
LRESULT CALLBACK |
cenButtonWndFn( |
HWND hwnd, |
UINT message, |
WPARAM wParam, |
LPARAM lParam) |
{ |
/* This is the window proc for the pushbutton control. Most of */ |
/* the drawing is accomplished in the DrawPushButton() function. */ |
/* The code below is mainly concerned with the keyboard and mouse */ |
/* events that the control detects. */ |
|
switch( message) { |
HANDLE_MSG( hwnd, WM_CREATE, cenButton_OnCreate); |
/*HANDLE_MSG( hwnd, WM_ENABLE, cenButton_OnEnable);*/ |
HANDLE_MSG( hwnd, WM_SETFOCUS, cenButton_OnSetFocus); |
HANDLE_MSG( hwnd, WM_KILLFOCUS, cenButton_OnKillFocus); |
HANDLE_MSG( hwnd, WM_LBUTTONDOWN, cenButton_OnLButtonDown); |
HANDLE_MSG( hwnd, WM_LBUTTONDBLCLK, cenButton_OnLButtonDown); |
HANDLE_MSG( hwnd, WM_LBUTTONUP, cenButton_OnLButtonUp); |
HANDLE_MSG( hwnd, WM_MOUSEMOVE, cenButton_OnMouseMove); |
/*HANDLE_MSG( hwnd, WM_KEYDOWN, cenButton_OnKey);*/ |
/*HANDLE_MSG( hwnd, WM_KEYUP, cenButton_OnKey);*/ |
HANDLE_MSG( hwnd, WM_ERASEBKGND, cenButton_OnEraseBkgnd); |
HANDLE_MSG( hwnd, WM_PAINT_SPECIAL, cenButton_OnPaint); |
/*HANDLE_MSG( hwnd, WM_GETDLGCODE, cenButton_OnGetDlgCode);*/ |
HANDLE_MSG( hwnd, BM_SETSTYLE, cenButton_OnSetStyle); |
HANDLE_MSG( hwnd, BM_GETSTATE, cenButton_OnGetState); |
HANDLE_MSG( hwnd, BM_SETSTATE, cenButton_OnSetState); |
/*HANDLE_MSG( hwnd, WM_DESTROY, cenButton_OnDestroy);*/ |
/*HANDLE_MSG( hwnd, WM_SETFONT, cenButton_OnSetFont);*/ |
HANDLE_MSG( hwnd, WM_SETTEXT, cenButton_OnSetText); |
|
case BM_GETCHECK: |
#if 0 |
return cenButton_OnGetState(hwnd); |
#else |
return( ( GET_PBSTATE(hwnd) & PUSH_CHECKED) == PUSH_CHECKED); |
#endif |
|
case BM_SETCHECK: |
#if 0 |
cenButton_OnSetState(hwnd, (WORD)wParam); |
#else |
{ |
WORD wStateOld; |
|
wStateOld = cenButton_FnStart( hwnd); |
cenButton_SetState( hwnd, PUSH_CHECKED, |
((WORD)wParam ? TRUE : FALSE) ); |
cenButton_FnEnd( hwnd, wStateOld); |
} |
#endif |
return 0; |
} |
|
return DefWindowProc( hwnd, message, wParam, lParam); |
} |
|
/* backwards compatibility*/ |
int WINAPI |
MwButtonRegister(HINSTANCE hInstance) |
{ |
return MwRegisterButtonControl(hInstance); |
} |
|
int WINAPI |
MwRegisterButtonControl(HINSTANCE hInstance) |
{ |
WNDCLASS wc; |
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; |
wc.lpfnWndProc = (WNDPROC)cenButtonWndFn; |
wc.cbClsExtra = 0; |
wc.cbWndExtra = 10; |
wc.hInstance = hInstance; |
wc.hIcon = NULL; |
wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/ |
wc.hbrBackground= GetStockObject(LTGRAY_BRUSH); |
wc.lpszMenuName = NULL; |
wc.lpszClassName= "BUTTON"; |
|
return RegisterClass(&wc); |
} |
|
static void WINAPI |
DrawGroupBox(HWND hwnd,HDC hDCwParam,DWORD dwStyle) |
{ |
HDC hdc; |
HFONT hFont; |
RECT rcClient; |
RECT rcText; |
RECT rc; |
PAINTSTRUCT ps; |
char buf[256]; |
HPEN hPenTop, hPenBottom, holdPen; |
COLORREF crTop,crBottom; |
|
|
hdc = BeginPaint(hwnd, &ps); |
if(!hdc) |
goto Return; |
|
GetWindowText(hwnd, buf, sizeof(buf)); |
GetClientRect( hwnd, &rcClient ); |
|
hFont = GetStockObject( DEFAULT_GUI_FONT); |
if (hFont) |
hFont = SelectObject(hdc,hFont); |
|
rc.left = 0; |
rc.top = 0; |
DrawText( hdc, buf, -1, &rc, DT_CALCRECT); |
|
if(buf[ 0]) { |
SetTextColor(hdc,GetSysColor(COLOR_WINDOWTEXT)); |
SetBkMode(hdc,TRANSPARENT); |
SetRect(&rcText,8,2,rc.right+8,rc.bottom+2); |
DrawText(hdc,buf,-1,&rcText,DT_CENTER); |
} |
|
crTop=GetSysColor(COLOR_BTNHIGHLIGHT); |
crBottom=GetSysColor(COLOR_BTNSHADOW); |
|
hPenTop = CreatePen( PS_SOLID, 1, crTop); |
hPenBottom = CreatePen( PS_SOLID, 1, crBottom); |
holdPen = SelectObject( hdc, hPenTop); |
|
MoveToEx(hdc,0,rc.bottom/2,NULL); |
|
if(buf[ 0]) { |
LineTo(hdc,5,rc.bottom/2); |
MoveToEx(hdc,rc.right+11,rc.bottom/2,NULL); |
LineTo(hdc,rcClient.right-1,rc.bottom/2); |
} |
else |
LineTo(hdc,rcClient.right-1,rc.bottom/2); |
|
LineTo(hdc,rcClient.right-1,rcClient.bottom-1); |
|
SelectObject( hdc, hPenBottom); |
LineTo(hdc,rcClient.left,rcClient.bottom-1); |
LineTo(hdc,rcClient.left,rc.bottom/2); |
|
SelectObject( hdc, holdPen); |
DeleteObject( hPenTop); |
DeleteObject( hPenBottom); |
|
if (hFont) |
SelectObject(hdc,hFont); |
|
Return: |
EndPaint(hwnd, &ps); |
} |
|
/* temporarily here, should move to winuser.c*/ |
void WINAPI |
CheckRadioButton(HWND hDlg, int nIDFirst,int nIDLast,int nIDCheckButton) |
{ |
HWND hWndCheck,hWndTemp; |
DWORD dwStyle; |
|
if (!(hWndCheck = GetDlgItem(hDlg,nIDCheckButton))) |
return; |
|
for(hWndTemp=hDlg->children; hWndTemp; hWndTemp=hWndTemp->siblings) { |
if(hWndCheck == hWndTemp) continue; |
dwStyle = GetWindowLong(hWndTemp,GWL_STYLE); |
if ((hWndTemp->id >= (WORD)nIDFirst) && |
(hWndTemp->id <= (WORD)nIDLast) && |
((LOWORD(dwStyle) == BS_RADIOBUTTON) || |
(LOWORD(dwStyle) == BS_AUTORADIOBUTTON))) |
SendMessage(hWndTemp,BM_SETCHECK,FALSE,0); |
} |
SendMessage(hWndCheck,BM_SETCHECK,TRUE,0); |
} |
/mwuser.c
0,0 → 1,7
#include "windows.h" |
|
int |
MwUserInit(int ac,char **av) |
{ |
return 0; |
} |
/draw3d.c
0,0 → 1,144
#include "windows.h" |
#include "wintools.h" |
/* |
* WIN Draw Library |
* Draw3dShadow - draws a shadow with bottom-left and top-right missing |
* Draw3dBox - draws a complete shadow |
* Draw3dInset - draw a 2 line 3d inset |
* Draw3dOutset - draw a 2 line 3d outset |
*/ |
|
/* |
* Draw3dShadow |
* NOINDENT_BLACK T=white, B=black |
* NOINDENT_GRAY T=white, B=dkgray |
* INDENT_BLACK T=black, B=white |
* INDENT_GRAY T=dkgray, B=white |
* |
* TTTTTTTTTTTTTT |
* T B |
* T B |
* BBBBBBBBBBBBBB |
*/ |
void WINAPI |
Draw3dShadow(HDC hDC,int x,int y,int w,int h,COLORREF crTop,COLORREF crBottom) |
{ |
HPEN hPenTop, hPenBottom, holdPen; |
|
hPenTop = CreatePen( PS_SOLID, 1, crTop); |
hPenBottom = CreatePen( PS_SOLID, 1, crBottom); |
holdPen = SelectObject( hDC, hPenTop); |
MoveToEx( hDC, x, y+h-2, NULL); |
LineTo( hDC, x, y); /* left side*/ |
LineTo( hDC, x+w-1, y); /* top side*/ |
|
SelectObject( hDC, hPenBottom); |
MoveToEx( hDC, x+w-1, y+1, NULL); |
LineTo( hDC, x+w-1, y+h-1); /* right side*/ |
LineTo( hDC, x, y+h-1); /* bottom side*/ |
|
SelectObject( hDC, holdPen); |
DeleteObject( hPenTop); |
DeleteObject( hPenBottom); |
} |
|
/* |
* Draw3dBox |
* |
* TTTTTTTTTTTTTTB |
* T B |
* T B |
* BBBBBBBBBBBBBBB |
*/ |
void WINAPI |
Draw3dBox(HDC hDC,int x,int y,int w,int h,COLORREF crTop,COLORREF crBottom) |
{ |
HPEN hPenTop, hPenBottom, holdPen; |
|
hPenTop = CreatePen( PS_SOLID, 1, crTop); |
hPenBottom = CreatePen( PS_SOLID, 1, crBottom); |
holdPen = SelectObject( hDC, hPenTop); |
MoveToEx( hDC, x, y+h-2, NULL); |
LineTo( hDC, x, y); /* left side*/ |
MoveToEx( hDC, x, y, NULL); |
LineTo( hDC, x+w-1, y); /* top side*/ |
|
SelectObject( hDC, hPenBottom); |
MoveToEx( hDC, x+w-1, y, NULL); |
LineTo( hDC, x+w-1, y+h-1); /* right side*/ |
LineTo( hDC, x-1, y+h-1); /* bottom side*/ |
|
SelectObject( hDC, holdPen); |
DeleteObject( hPenTop); |
DeleteObject( hPenBottom); |
} |
|
/* |
* Draw 2 line deep 3d inset |
*/ |
void WINAPI |
Draw3dInset(HDC hDC,int x,int y,int w,int h) |
{ |
Draw3dBox(hDC, x, y, w, h, |
GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT)); |
++x; ++y; w -= 2; h -= 2; |
Draw3dBox(hDC, x, y, w, h, |
GetSysColor(COLOR_WINDOWFRAME), GetSysColor(COLOR_3DLIGHT)); |
} |
|
/* |
* Draw 2 line deep 3d outset |
*/ |
void WINAPI |
Draw3dOutset(HDC hDC,int x,int y,int w,int h) |
{ |
Draw3dBox(hDC, x, y, w, h, |
GetSysColor(COLOR_3DLIGHT), GetSysColor(COLOR_WINDOWFRAME)); |
++x; ++y; w -= 2; h -= 2; |
Draw3dBox(hDC, x, y, w, h, |
GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_BTNSHADOW)); |
} |
|
/* |
* Draw 1 line pushed down rectangle |
*/ |
void WINAPI |
Draw3dPushDown(HDC hDC, int x, int y, int w, int h) |
{ |
Draw3dBox(hDC, x, y, w, h, GetSysColor(COLOR_BTNSHADOW), |
GetSysColor(COLOR_BTNSHADOW)); |
} |
|
/* |
* Draw either 3d up or down depending on state |
*/ |
void WINAPI |
Draw3dUpDownState(HDC hDC, int x, int y, int w, int h, BOOL fDown) |
{ |
if (fDown) |
Draw3dPushDown(hDC, x, y, w, h); |
else Draw3dOutset(hDC, x, y, w, h); |
} |
|
void WINAPI |
Draw3dUpFrame(HDC hDC, int l, int t, int r, int b) |
{ |
RECT rc; |
HBRUSH hbr; |
|
SetRect(&rc, l, t, r, b); |
Draw3dBox(hDC, rc.left, rc.top, |
rc.right-rc.left, rc.bottom-rc.top, |
GetSysColor(COLOR_3DLIGHT), |
GetSysColor(COLOR_WINDOWFRAME)); |
InflateRect(&rc, -1, -1); |
Draw3dBox(hDC, rc.left, rc.top, |
rc.right-rc.left, rc.bottom-rc.top, |
GetSysColor(COLOR_BTNHIGHLIGHT), |
GetSysColor(COLOR_BTNSHADOW)); |
InflateRect(&rc, -1, -1); |
|
hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); |
FillRect(hDC, &rc, hbr); |
DeleteObject(hbr); |
} |
/listbox.c
0,0 → 1,1688
/* |
* Copyright (C) 1999, 2000, Wei Yongming. |
* Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com> |
* |
* Listbox for Microwindows win32 api. |
*/ |
|
/* |
** This library is free software; you can redistribute it and/or |
** modify it under the terms of the GNU Library General Public |
** License as published by the Free Software Foundation; either |
** version 2 of the License, or (at your option) any later version. |
** |
** This library is distributed in the hope that it will be useful, |
** but WITHOUT ANY WARRANTY; without even the implied warranty of |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
** Library General Public License for more details. |
** |
** You should have received a copy of the GNU Library General Public |
** License along with this library; if not, write to the Free |
** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
** MA 02111-1307, USA |
*/ |
|
/* |
** Alternatively, the contents of this file may be used under the terms |
** of the Mozilla Public License (the "MPL License") in which case the |
** provisions of the MPL License are applicable instead of those above. |
*/ |
|
/* Note: |
** Although there was a version by Zhao Jianghua, this version of |
** LISTBOX control is written by Wei Yongming from scratch. |
** |
** Modify records: |
** |
** Who When Where For What Status |
**----------------------------------------------------------------------------- |
** Wei Yongming 1999/10/18 Tsinghua Item Additional Data Finished |
** Wei Yongming 1999/10/31 Tsinghua Space bar for checkmark Finished |
** Wei Yongming 1999/10/31 Tsinghua Character match item Finished |
** Wei Yongming 1999/11/07 Tsinghua Character match item Bug fixing |
** WEI Yongming 2000/01/20 Tsinghua Thumb dragging Finished |
** WEI Yongming 2000/02/24 Tsinghua Add MPL License Finished |
** Kevin Tseng 2000/05/26 gv port to microwin ported |
** Greg Haerr 2000/06/15 Utah 3d look, bug fixes Finished |
** Kevin Tseng 2000/06/22 gv port to mw-nanox ported |
** Kevin Tseng 2000/06/22 gv fixed bug if no item Finished |
** Kevin Tseng 2000/08/08 gv enable scrollbar(V) porting |
** Kevin Tseng 2000/08/10 gv enable scrollbar(V) ported |
** Kevin Tseng 2000/08/10 gv WM_CHAR, WM_KEYDOWN ported |
** |
** TODO: |
** 1. Multiple columns support. |
*/ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#define MWINCLUDECOLORS |
#include "windows.h" |
#include "wintools.h" /* Draw3dBox */ |
#include "device.h" /* GdGetTextSize */ |
|
#define FixStrAlloc(n) malloc((n)+1) |
#define FreeFixStr(p) free(p) |
|
#define LBIF_NORMAL 0x0000L |
#define LBIF_SELECTED 0x0001L |
#define LBIF_CHECKED 0x0010L |
#define LBIF_PARTCHECKED 0x0020L |
#define LBIF_CHECKMARKMASK 0x00F0L |
|
#define CMFLAG_BLANK 0 |
#define CMFLAG_CHECKED 1 |
#define CMFLAG_PARTCHECKED 2 |
typedef struct _LISTBOXITEMINFO { |
int insPos; /* insert position */ |
char* string; /* item string */ |
int cmFlag; /* check mark flag */ |
HICON hIcon; /* handle of icon */ |
} LISTBOXITEMINFO, *PLISTBOXITEMINFO; |
|
typedef struct _LISTBOXITEM { |
char* key; /* item sort key */ |
DWORD dwFlags; /* item flags */ |
DWORD dwData; /* item data */ |
DWORD dwAddData; /* item additional data */ |
struct _LISTBOXITEM* next; /* next item */ |
} LISTBOXITEM, *PLISTBOXITEM; |
|
#define DEF_LB_BUFFER_LEN 5 |
|
#define LBF_FOCUS 0x0001 |
#define LBF_NOTHINGSELECTED 0x0002 |
|
typedef struct _LISTBOXDATA { |
DWORD dwFlags; /* listbox flags */ |
|
int itemCount; /* items count */ |
int itemTop; /* start display item */ |
int itemVisibles; /* number of visible items */ |
|
int itemHilighted; /* current hilighted item */ |
int itemHeight; /* item height */ |
|
LISTBOXITEM* head; /* items linked list head */ |
|
int buffLen; /* buffer length */ |
LISTBOXITEM* buffStart; /* buffer start */ |
LISTBOXITEM* buffEnd; /* buffer end */ |
LISTBOXITEM* freeList; /* free list in buffer */ |
} LISTBOXDATA, *PLISTBOXDATA; |
|
void ListboxControlCleanup (); |
static LRESULT CALLBACK |
ListboxCtrlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); |
|
#define ITEM_BOTTOM(x) (x->itemTop + x->itemVisibles - 1) |
|
#define LST_WIDTH_CHECKMARK 11 |
#define LST_HEIGHT_CHECKMARK 11 |
#define LST_INTER_BMPTEXT 2 |
|
int WINAPI MwRegisterListboxControl(HINSTANCE hInstance) |
{ |
WNDCLASS wc; |
#if 0 |
static BITMAP sg_bmpCheckMark; |
if (!LoadSystemBitmap (&sg_bmpCheckMark, "checkmark")) { |
fprintf (stderr, "Load ListBox Check Mark Bitmap failure!\n"); |
return FALSE; |
} |
#endif |
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; |
wc.lpfnWndProc = (WNDPROC)ListboxCtrlProc; |
wc.cbClsExtra = 0; |
wc.cbWndExtra = 0; |
wc.hInstance = hInstance; |
wc.hIcon = NULL; |
wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/ |
wc.hbrBackground= GetStockObject(WHITE_BRUSH); |
wc.lpszMenuName = NULL; |
wc.lpszClassName= "LISTBOX"; |
|
return RegisterClass(&wc); |
} |
|
void ListboxControlCleanup () |
{ |
#if 0 |
UnloadBitmap (&sg_bmpCheckMark); |
#endif |
} |
|
static LRESULT NotifyParent (HWND hwnd, int id, int code) |
{ |
return SendMessage (GetParent (hwnd), WM_COMMAND, |
(WPARAM) MAKELONG (id, code), (LPARAM)hwnd); |
} |
|
static BOOL lstInitListBoxData (HWND hwnd,LISTBOXDATA* pData, int len) |
{ |
int i, xw, xh, xb; |
PLISTBOXITEM plbi; |
HDC hdc; |
|
memset (pData, 0, sizeof (LISTBOXDATA)); |
#if 0 |
pData->itemHeight = GetSysCharHeight (); |
#else |
hdc=GetDC(hwnd); |
#if MWCLIENT /* nanox client */ |
GrSetGCFont(hdc->gc,hdc->font->fontid); |
GrGetGCTextSize(hdc->gc,"X",1, |
MWTF_ASCII,&xw,&xh,&xb); |
#else |
GdSetFont(hdc->font->pfont); |
GdGetTextSize(hdc->font->pfont,"X",1, |
&xw,&xh,&xb,MWTF_ASCII); |
#endif |
ReleaseDC(hwnd,hdc); |
pData->itemHeight=xh + 1; |
#endif |
pData->itemHilighted = 0; |
pData->dwFlags = LBF_NOTHINGSELECTED; |
|
/* init item buffer. */ |
if (!(pData->buffStart = malloc (len * sizeof (LISTBOXITEM)))) |
return FALSE; |
|
pData->buffLen = len; |
pData->buffEnd = pData->buffStart + len; |
pData->freeList = pData->buffStart; |
|
plbi = pData->freeList; |
for (i = 0; i < len - 1; i++) { |
plbi->next = plbi + 1; |
plbi ++; |
} |
plbi->next = NULL; |
|
return TRUE; |
} |
|
static void lstListBoxCleanUp (LISTBOXDATA* pData) |
{ |
PLISTBOXITEM plbi; |
PLISTBOXITEM next; |
|
plbi = pData->head; |
while (plbi) { |
FreeFixStr (plbi->key); |
next = plbi->next; |
if (plbi < pData->buffStart || plbi > pData->buffEnd) |
free (plbi); |
|
plbi = next; |
} |
|
free (pData->buffStart); |
} |
|
static void lstResetListBoxContent (PLISTBOXDATA pData) |
{ |
int i; |
PLISTBOXITEM plbi, next; |
|
pData->itemCount = 0; |
pData->itemTop = 0; |
pData->itemHilighted = 0; |
#if 0 |
pData->itemVisibles = 0; |
#endif |
|
plbi = pData->head; |
while (plbi) { |
FreeFixStr (plbi->key); |
next = plbi->next; |
if (plbi < pData->buffStart || plbi > pData->buffEnd) |
free (plbi); |
|
plbi = next; |
} |
|
pData->head = NULL; |
pData->freeList = pData->buffStart; |
|
plbi = pData->freeList; |
for (i = 0; i < pData->buffLen - 1; i++) { |
plbi->next = plbi + 1; |
plbi ++; |
} |
plbi->next = NULL; |
} |
|
static PLISTBOXITEM lstAllocItem (PLISTBOXDATA pData) |
{ |
PLISTBOXITEM plbi; |
|
if (pData->freeList) { |
plbi = pData->freeList; |
pData->freeList = plbi->next; |
} |
else |
plbi = (PLISTBOXITEM) malloc (sizeof (LISTBOXITEM)); |
|
return plbi; |
} |
|
static void lstFreeItem (PLISTBOXDATA pData, PLISTBOXITEM plbi) |
{ |
if (plbi < pData->buffStart || plbi > pData->buffEnd) |
free (plbi); |
else { |
plbi->next = pData->freeList; |
pData->freeList = plbi; |
} |
} |
|
static int lstAddNewItem (DWORD dwStyle, |
PLISTBOXDATA pData, PLISTBOXITEM newItem, int pos) |
{ |
PLISTBOXITEM plbi; |
PLISTBOXITEM insPosItem = NULL; |
int insPos = 0; |
|
newItem->next = NULL; |
if (!pData->head) |
insPosItem = NULL; |
else if (dwStyle & LBS_SORT) { |
plbi = pData->head; |
|
if (strcmp (newItem->key, plbi->key) < 0) { |
insPosItem = NULL; |
insPos = 0; |
} |
else { |
while (plbi->next) { |
if (strcmp (newItem->key, plbi->next->key) <= 0) |
break; |
|
plbi = plbi->next; |
insPos ++; |
} |
insPosItem = plbi; |
} |
} |
else { |
plbi = pData->head; |
|
if (pos < 0) { |
while (plbi->next) { |
plbi = plbi->next; |
insPos ++; |
} |
insPosItem = plbi; |
} |
else if (pos > 0) { |
int index = 0; |
|
while (plbi->next) { |
if (pos == index) |
break; |
plbi = plbi->next; |
index ++; |
insPos ++; |
} |
insPosItem = plbi; |
} |
} |
|
if (insPosItem) { |
plbi = insPosItem->next; |
insPosItem->next = newItem; |
newItem->next = plbi; |
|
insPos ++; |
} |
else { |
plbi = pData->head; |
pData->head = newItem; |
newItem->next = plbi; |
} |
|
pData->itemCount ++; |
return insPos; |
} |
|
static PLISTBOXITEM lstRemoveItem (PLISTBOXDATA pData, int* pos) |
{ |
int index = 0; |
PLISTBOXITEM plbi, prev; |
|
if (!pData->head) |
return NULL; |
|
if (*pos < 0) { |
prev = pData->head; |
plbi = pData->head; |
while (plbi->next) { |
prev = plbi; |
plbi = plbi->next; |
index ++; |
} |
|
if (plbi == pData->head) { |
pData->head = pData->head->next; |
*pos = 0; |
return plbi; |
} |
else { |
prev->next = plbi->next; |
*pos = index; |
return plbi; |
} |
} |
else if (*pos == 0) { |
plbi = pData->head; |
pData->head = plbi->next; |
return plbi; |
} |
else { |
index = 0; |
prev = pData->head; |
plbi = pData->head; |
while (plbi->next) { |
if (*pos == index) |
break; |
|
prev = plbi; |
plbi = plbi->next; |
index ++; |
} |
|
if (plbi == pData->head) { |
pData->head = pData->head->next; |
*pos = 0; |
return plbi; |
} |
else { |
prev->next = plbi->next; |
*pos = index; |
return plbi; |
} |
} |
|
return NULL; |
} |
|
static void lstGetItemsRect (PLISTBOXDATA pData, int start, int end, RECT* prc) |
{ |
if (start < 0) |
start = 0; |
|
prc->top = (start - pData->itemTop)*pData->itemHeight; |
|
if (end >= 0) |
prc->bottom = (end - pData->itemTop + 1)*pData->itemHeight; |
|
} |
|
static void lstInvalidateItem (HWND hwnd, PLISTBOXDATA pData, int pos,BOOL fEBk) |
{ |
RECT rcInv; |
|
if (pos < pData->itemTop || pos > (pData->itemTop + pData->itemVisibles)) |
return; |
|
GetClientRect (hwnd, &rcInv); |
rcInv.top = (pos - pData->itemTop)*pData->itemHeight; |
rcInv.bottom = rcInv.top + pData->itemHeight; |
|
InvalidateRect (hwnd, &rcInv, fEBk); |
} |
|
static BOOL lstInvalidateUnderItem (HWND hwnd, PLISTBOXDATA pData, int pos) |
{ |
RECT rcInv; |
|
if (pos > (pData->itemTop + pData->itemVisibles)) |
return FALSE; |
|
if (pos <= pData->itemTop) { |
InvalidateRect (hwnd, NULL, TRUE); |
return TRUE; |
} |
|
GetClientRect (hwnd, &rcInv); |
|
lstGetItemsRect (pData, pos, -1, &rcInv); |
|
if (rcInv.top < rcInv.bottom) |
InvalidateRect (hwnd, &rcInv, TRUE); |
|
return TRUE; |
} |
|
static PLISTBOXITEM lstGetItem (PLISTBOXDATA pData, int pos) |
{ |
int i; |
PLISTBOXITEM plbi; |
|
plbi = pData->head; |
for (i=0; i < pos && plbi; i++) |
plbi = plbi->next; |
|
return plbi; |
} |
|
static int lstFindItem (PLISTBOXDATA pData, int start, char* key, BOOL bExact) |
{ |
PLISTBOXITEM plbi; |
int keylen = strlen (key); |
|
if (start >= (pData->itemCount - 1)) |
start = 0; |
|
plbi = lstGetItem (pData, start); |
|
while (plbi) |
{ |
if (bExact && (keylen != strlen (plbi->key))) { |
plbi = plbi->next; |
start ++; |
continue; |
} |
|
if (strncasecmp (key, plbi->key, keylen) == 0) |
return start; |
|
plbi = plbi->next; |
start ++; |
} |
|
return LB_ERR; |
} |
|
static void lstOnDrawSListBoxItems (HDC hdc, DWORD dwStyle, |
PLISTBOXDATA pData, int width) |
{ |
PLISTBOXITEM plbi; |
int i; |
int x = 0, y = 0; |
int offset; |
RECT rc; |
COLORREF bk; |
|
plbi = lstGetItem (pData, pData->itemTop); |
|
for (i = 0; plbi && i < (pData->itemVisibles + 1); i++) { |
|
if (plbi->dwFlags & LBIF_SELECTED) { |
SetBkColor (hdc, bk = BLUE); |
SetTextColor (hdc, WHITE); |
} |
else { |
SetBkColor (hdc, bk = WHITE); |
SetTextColor (hdc, BLACK); |
} |
rc.left = 0; |
rc.top = y; |
rc.right = width; |
rc.bottom = y + pData->itemHeight; |
FastFillRect(hdc, &rc, bk); |
|
if (dwStyle & LBS_CHECKBOX) { |
x = LST_INTER_BMPTEXT; |
if (plbi->dwFlags & LBIF_CHECKED) |
offset = 0; |
else if (plbi->dwFlags & LBIF_PARTCHECKED) |
offset = LST_WIDTH_CHECKMARK << 1; |
else |
offset = LST_WIDTH_CHECKMARK; |
#if 0 /* fix: no bitmap */ |
FillBoxWithBitmapPart (hdc, |
x, y + ((pData->itemHeight - LST_HEIGHT_CHECKMARK)>>1), |
LST_WIDTH_CHECKMARK, LST_HEIGHT_CHECKMARK, |
0, 0, |
&sg_bmpCheckMark, |
offset, 0); |
#endif |
x += LST_WIDTH_CHECKMARK + LST_INTER_BMPTEXT; |
} |
#if 0 /* fix: no icon */ |
if (dwStyle & LBS_USEICON && plbi->dwData) { |
DrawIcon (hdc, |
x, y, pData->itemHeight, pData->itemHeight, |
(HICON) plbi->dwData); |
x += pData->itemHeight + LST_INTER_BMPTEXT; |
} |
#endif |
|
/* jmt: should be SYSTEM_FIXED_FONT because of minigui's GetSysCharXXX() */ |
#if 0 |
SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); |
#endif |
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); |
TextOut (hdc, x+2, y, plbi->key,-1); |
|
y += pData->itemHeight; |
plbi = plbi->next; |
} |
} |
|
static int lstSelectItem (DWORD dwStyle, PLISTBOXDATA pData, int newSel) |
{ |
PLISTBOXITEM plbi, newItem; |
int index; |
|
newItem = lstGetItem (pData, newSel); |
#if 1 /* jmt: fixed if no item added */ |
if (!newItem) return -1; |
#endif |
#ifdef _DEBUG |
if (!newItem) |
fprintf (stderr, "ASSERT failed: return value of lstGetItem" |
" in lstSelectItem.\n"); |
#endif |
|
if (dwStyle & LBS_MULTIPLESEL) { |
newItem->dwFlags ^= LBIF_SELECTED; |
return newSel; |
} |
|
index = 0; |
plbi = pData->head; |
while (plbi) { |
if (plbi->dwFlags & LBIF_SELECTED) { |
if (index != newSel) { |
plbi->dwFlags &= ~LBIF_SELECTED; |
newItem->dwFlags |= LBIF_SELECTED; |
return index; |
} |
break; |
} |
|
plbi = plbi->next; |
index ++; |
} |
|
newItem->dwFlags |= LBIF_SELECTED; |
return -1; |
} |
|
static void lstDrawFocusRect (HDC hdc, PLISTBOXDATA pData, RECT* rc) |
{ |
HGDIOBJ oldbrush,oldpen; |
|
if (pData->itemHilighted < pData->itemTop |
|| pData->itemHilighted > (pData->itemTop + pData->itemVisibles)) |
return; |
|
if (pData->dwFlags & LBF_FOCUS) { |
lstGetItemsRect (pData, pData->itemHilighted, pData->itemHilighted, rc); |
#if 0 |
InflateRect (rc, -1, -1); |
|
FocusRect (hdc, rc->left - 1, rc->top, rc->right, rc->bottom); |
#else |
oldbrush=SelectObject(hdc, GetStockObject(NULL_BRUSH)); |
oldpen=SelectObject(hdc, CreatePen(PS_SOLID, 1, |
GetSysColor(COLOR_BTNHIGHLIGHT))); |
#if 0 |
GdSetMode(MWMODE_XOR); |
#endif |
Rectangle (hdc, rc->left, rc->top, rc->right, rc->bottom); |
#if 0 |
GdSetMode(MWMODE_SET); |
#endif |
SelectObject(hdc,oldbrush); |
DeleteObject(SelectObject(hdc,oldpen)); |
#endif |
} |
} |
|
static void lstCalcParams (const RECT* rcClient, PLISTBOXDATA pData) |
{ |
#define RECTHP(prc) (prc->bottom - prc->top) |
pData->itemVisibles = (RECTHP (rcClient)) / pData->itemHeight; |
|
#if 1 /* test calculation of itemVisibles */ |
if( ((RECTHP (rcClient)) % pData->itemHeight) ) |
pData->itemVisibles++; |
#endif |
} |
|
extern BOOL SetScrollPos (HWND hWnd, int iSBar, int iNewPos); |
extern BOOL EnableScrollBar (HWND hWnd, int iSBar, BOOL bEnable); |
|
static void lstSetVScrollInfo (HWND hwnd, PLISTBOXDATA pData, BOOL fRedraw) |
{ |
SCROLLINFO si; |
|
if (pData->itemVisibles >= pData->itemCount) |
{ |
SetScrollPos (hwnd, SB_VERT, 0); |
EnableScrollBar (hwnd, SB_VERT, FALSE); |
return; |
} |
|
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; |
si.nMax = pData->itemCount - 1; |
si.nMin = 0; |
si.nPage = min (pData->itemVisibles, (pData->itemCount - pData->itemTop)); |
si.nPos = pData->itemTop; |
|
SetScrollInfo (hwnd, SB_VERT, &si, fRedraw); |
EnableScrollBar (hwnd, SB_VERT, TRUE); |
} |
|
LRESULT CALLBACK |
ListboxCtrlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) |
{ |
HDC hdc; |
HWND pCtrl; |
PLISTBOXDATA pData; |
DWORD dwStyle; |
|
pCtrl = hwnd; |
dwStyle = pCtrl->style; |
|
switch (message) |
{ |
case WM_CREATE: |
pData = (LISTBOXDATA*) malloc (sizeof(LISTBOXDATA)); |
if (pData == NULL) |
return -1; |
|
pCtrl->userdata = (DWORD)pData; |
if (!lstInitListBoxData (hwnd, pData, DEF_LB_BUFFER_LEN)) { |
free (pData); |
return -1; |
} |
break; |
|
case WM_SIZE: |
{ |
RECT rc; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
GetClientRect(hwnd, &rc); |
lstCalcParams (&rc, pData); |
} |
break; |
|
case WM_DESTROY: |
pData = (PLISTBOXDATA)pCtrl->userdata; |
lstListBoxCleanUp (pData); |
free (pData); |
break; |
|
case LB_RESETCONTENT: |
pData = (PLISTBOXDATA)pCtrl->userdata; |
lstResetListBoxContent (pData); |
InvalidateRect (hwnd, NULL, TRUE); |
break; |
|
case LB_ADDSTRING: |
case LB_INSERTSTRING: |
{ |
char* string = NULL; |
PLISTBOXITEMINFO plbii = NULL; |
PLISTBOXITEM newItem; |
int pos; |
|
if (dwStyle & LBS_CHECKBOX || dwStyle & LBS_USEICON) { |
plbii = (PLISTBOXITEMINFO)lParam; |
if (!plbii) |
return LB_ERR; |
|
string = plbii->string; |
} |
else { |
string = (char*)lParam; |
if (string == NULL || string [0] == '\0') |
return LB_ERR; |
} |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
newItem = lstAllocItem (pData); |
if (!newItem) { |
NotifyParent (hwnd, pCtrl->id, LBN_ERRSPACE); |
return LB_ERRSPACE; |
} |
|
newItem->key = FixStrAlloc (strlen (string)); |
strcpy (newItem->key, string); |
newItem->dwFlags = LBIF_NORMAL; |
if (plbii) { |
switch (plbii->cmFlag) { |
case CMFLAG_CHECKED: |
newItem->dwFlags |= LBIF_CHECKED; |
break; |
case CMFLAG_PARTCHECKED: |
newItem->dwFlags |= LBIF_PARTCHECKED; |
break; |
} |
|
if (dwStyle & LBS_USEICON) |
newItem->dwData = (DWORD)plbii->hIcon; |
else |
newItem->dwData = 0L; |
} |
newItem->dwAddData = 0L; |
|
if (message == LB_ADDSTRING) |
pos = lstAddNewItem (dwStyle, pData, newItem, -1); |
else |
pos = lstAddNewItem (dwStyle, pData, newItem, (int)wParam); |
|
lstInvalidateUnderItem (hwnd, pData, pos); |
|
lstSetVScrollInfo (hwnd, pData, TRUE); |
|
return pos; |
} |
break; |
|
case LB_DELETESTRING: |
{ |
PLISTBOXITEM removed; |
int delete; |
|
delete = (int)wParam; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
removed = lstRemoveItem (pData, &delete); |
if (removed) { |
FreeFixStr (removed->key); |
lstFreeItem (pData, removed); |
|
pData->itemCount --; |
|
if (pData->itemTop != 0 |
&& pData->itemCount <= pData->itemVisibles) { |
pData->itemTop = 0; |
InvalidateRect (hwnd, NULL, TRUE); |
} |
else { |
lstInvalidateUnderItem (hwnd, pData, delete); |
if (delete <= pData->itemTop) { |
pData->itemTop --; |
if (pData->itemTop < 0) |
pData->itemTop = 0; |
} |
} |
|
if (pData->itemHilighted >= pData->itemCount) { |
pData->itemHilighted = pData->itemCount - 1; |
if (pData->itemHilighted < 0) |
pData->itemHilighted = 0; |
} |
|
if (pData->itemHilighted < pData->itemTop) |
pData->itemHilighted = pData->itemTop; |
if (pData->itemHilighted > ITEM_BOTTOM (pData)) |
pData->itemHilighted = ITEM_BOTTOM (pData); |
|
lstSetVScrollInfo (hwnd, pData, TRUE); |
} |
} |
break; |
|
case LB_FINDSTRING: |
if( *(char*)lParam == '\0' ) |
return LB_ERR; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
return lstFindItem(pData, (int)wParam, (char*)lParam, FALSE); |
|
case LB_FINDSTRINGEXACT: |
if( *(char*)lParam == '\0' ) |
return LB_ERR; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
return lstFindItem(pData, (int)wParam, (char*)lParam, TRUE); |
|
case LB_SETTOPINDEX: |
{ |
int newTop = (int) wParam; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
|
if (newTop <0) |
newTop = 0; |
else if (newTop > pData->itemCount - pData->itemVisibles) |
newTop = pData->itemCount - pData->itemVisibles; |
|
if (pData->itemTop != newTop) { |
pData->itemTop = newTop; |
|
if (pData->itemHilighted < pData->itemTop) |
pData->itemHilighted = pData->itemTop; |
if (pData->itemHilighted > ITEM_BOTTOM (pData)) |
pData->itemHilighted = ITEM_BOTTOM (pData); |
|
lstSetVScrollInfo (hwnd, pData, TRUE); |
|
InvalidateRect (hwnd, NULL, TRUE); |
} |
} |
break; |
|
case LB_SETCURSEL: |
case LB_SETCARETINDEX: |
{ |
int new = (int)wParam; |
int old, newTop; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
if (new < 0 || new > pData->itemCount - 1) |
return LB_ERR; |
|
old = pData->itemHilighted; |
if (new >= 0 && new != old) { |
if (pData->itemCount - new >= pData->itemVisibles) |
newTop = new; |
else |
newTop = max (pData->itemCount - pData->itemVisibles, 0); |
|
pData->itemTop = newTop; |
pData->itemHilighted = new; |
lstSetVScrollInfo (hwnd, pData, TRUE); |
} |
|
if (!(dwStyle & LBS_MULTIPLESEL)) |
lstSelectItem (dwStyle, pData, new); |
InvalidateRect (hwnd, NULL, TRUE); |
|
return old; |
} |
break; |
|
case LB_GETCOUNT: |
pData = (PLISTBOXDATA)pCtrl->userdata; |
return pData->itemCount; |
break; |
|
case LB_GETCURSEL: |
{ |
PLISTBOXITEM plbi; |
int index = 0; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
if (dwStyle & LBS_MULTIPLESEL) |
return pData->itemHilighted; |
|
plbi = pData->head; |
while (plbi) { |
if (plbi->dwFlags & LBIF_SELECTED) |
return index; |
|
index ++; |
plbi = plbi->next; |
} |
|
return LB_ERR; |
} |
break; |
|
case LB_GETSELCOUNT: |
{ |
int nSel; |
PLISTBOXITEM plbi; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
|
nSel = 0; |
plbi = pData->head; |
while (plbi) { |
if (plbi->dwFlags & LBIF_SELECTED) |
nSel ++; |
plbi = plbi->next; |
} |
|
return nSel; |
} |
break; |
|
case LB_GETTOPINDEX: |
pData = (PLISTBOXDATA)pCtrl->userdata; |
return pData->itemTop; |
break; |
|
case LB_GETCARETINDEX: |
pData = (PLISTBOXDATA)pCtrl->userdata; |
return pData->itemHilighted; |
break; |
|
case LB_GETTEXTLEN: |
{ |
PLISTBOXITEM plbi; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
plbi = lstGetItem (pData, (int)wParam); |
if (plbi) |
return strlen (plbi->key); |
else |
return LB_ERR; |
} |
break; |
|
case LB_GETTEXT: |
{ |
PLISTBOXITEM plbi; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
plbi = lstGetItem (pData, (int)wParam); |
if (plbi) |
strcpy ((char*)lParam, plbi->key); |
else |
return LB_ERR; |
} |
break; |
|
case LB_SETTEXT: |
{ |
PLISTBOXITEM plbi; |
char* newStr; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
plbi = lstGetItem (pData, (int)wParam); |
if (plbi) { |
newStr = FixStrAlloc (strlen ((char*)lParam)); |
if (newStr) { |
FreeFixStr (plbi->key); |
plbi->key = newStr; |
strcpy (plbi->key, (char*)lParam); |
lstInvalidateItem (hwnd, pData, (int)wParam, TRUE); |
} |
else |
return LB_ERR; |
} |
else |
return LB_ERR; |
} |
break; |
|
case LB_GETITEMDATA: |
{ |
PLISTBOXITEM plbi; |
PLISTBOXITEMINFO plbii; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
if (!(plbi = lstGetItem (pData, (int)wParam))) |
return LB_ERR; |
|
if (!(dwStyle & LBS_CHECKBOX || dwStyle & LBS_USEICON)) { |
return plbi->dwData; |
} |
|
plbii = (PLISTBOXITEMINFO)lParam; |
if (!plbii) |
return LB_ERR; |
|
if (plbi->dwFlags & LBIF_CHECKED) |
plbii->cmFlag = CMFLAG_CHECKED; |
else if (plbi->dwFlags & LBIF_PARTCHECKED) |
plbii->cmFlag = CMFLAG_PARTCHECKED; |
else |
plbii->cmFlag = CMFLAG_BLANK; |
plbii->hIcon = (HICON)plbi->dwData; |
|
return LB_OKAY; |
} |
break; |
|
case LB_SETITEMDATA: |
{ |
PLISTBOXITEM plbi; |
PLISTBOXITEMINFO plbii; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
if (!(plbi = lstGetItem (pData, (int)wParam))) |
return LB_ERR; |
|
if (!(dwStyle & LBS_CHECKBOX || dwStyle & LBS_USEICON)) { |
plbi->dwData = (DWORD)lParam; |
return LB_OKAY; |
} |
|
plbii = (PLISTBOXITEMINFO)lParam; |
if (!plbii) |
return LB_ERR; |
|
plbi->dwFlags &= ~LBIF_CHECKMARKMASK; |
switch (plbii->cmFlag) { |
case CMFLAG_CHECKED: |
plbi->dwFlags |= LBIF_CHECKED; |
break; |
case CMFLAG_PARTCHECKED: |
plbi->dwFlags |= LBIF_PARTCHECKED; |
break; |
} |
|
if (dwStyle & LBS_USEICON) |
plbi->dwData = (DWORD)plbii->hIcon; |
else |
plbi->dwData = 0; |
|
lstInvalidateItem (hwnd, pData, (int)wParam, TRUE); |
|
return LB_OKAY; |
} |
break; |
|
case LB_GETITEMADDDATA: |
{ |
PLISTBOXITEM plbi; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
if (!(plbi = lstGetItem (pData, (int)wParam))) |
return LB_ERR; |
|
return plbi->dwAddData; |
} |
break; |
|
case LB_SETITEMADDDATA: |
{ |
PLISTBOXITEM plbi; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
if (!(plbi = lstGetItem (pData, (int)wParam))) |
return LB_ERR; |
|
plbi->dwAddData = (DWORD)lParam; |
|
return LB_OKAY; |
} |
break; |
|
case LB_GETCHECKMARK: |
{ |
PLISTBOXITEM plbi; |
|
if (!(dwStyle & LBS_CHECKBOX)) |
return LB_ERR; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
if (!(plbi = lstGetItem (pData, (int)wParam))) |
return LB_ERR; |
|
if (plbi->dwFlags & LBIF_CHECKED) |
return CMFLAG_CHECKED; |
|
if (plbi->dwFlags & LBIF_PARTCHECKED) |
return CMFLAG_PARTCHECKED; |
|
return CMFLAG_BLANK; |
} |
break; |
|
case LB_SETCHECKMARK: |
{ |
PLISTBOXITEM plbi; |
|
if (!(dwStyle & LBS_CHECKBOX)) |
return LB_ERR; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
if (!(plbi = lstGetItem (pData, (int)wParam))) |
return LB_ERR; |
|
plbi->dwFlags &= ~LBIF_CHECKMARKMASK; |
switch (lParam) { |
case CMFLAG_CHECKED: |
plbi->dwFlags |= LBIF_CHECKED; |
break; |
case CMFLAG_PARTCHECKED: |
plbi->dwFlags |= LBIF_PARTCHECKED; |
break; |
} |
|
lstInvalidateItem (hwnd, pData, (int)wParam, TRUE); |
|
return LB_OKAY; |
} |
break; |
|
case LB_GETSELITEMS: |
{ |
int nItem; |
int nSel = 0; |
int index = 0; |
int* pInt; |
PLISTBOXITEM plbi; |
|
nItem = (int)wParam; |
pInt = (int*)lParam; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
plbi = pData->head; |
while (plbi) { |
|
if (plbi->dwFlags & LBIF_SELECTED) { |
if (pInt) { |
if (nSel < nItem) |
*(pInt + nSel) = index; |
else |
return nItem; |
} |
nSel ++; |
} |
|
plbi = plbi->next; |
index ++; |
} |
|
return nSel; |
} |
break; |
|
case LB_GETSEL: |
{ |
PLISTBOXITEM plbi; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
plbi = lstGetItem (pData, (int)wParam); |
if (plbi) |
return plbi->dwFlags & LBIF_SELECTED; |
else |
return LB_ERR; |
} |
break; |
|
case LB_SETSEL: |
{ |
PLISTBOXITEM plbi; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
plbi = lstGetItem (pData, (int)lParam); |
if (plbi) { |
pData->dwFlags &= ~LBF_NOTHINGSELECTED; |
if (wParam == -1) |
plbi->dwFlags ^= LBIF_SELECTED; |
else if (wParam == 0) |
plbi->dwFlags &= ~LBIF_SELECTED; |
else |
plbi->dwFlags |= LBIF_SELECTED; |
|
lstInvalidateItem (hwnd, pData, (int)lParam, FALSE); |
} |
else |
return LB_ERR; |
} |
break; |
|
case LB_GETITEMHEIGHT: |
pData = (PLISTBOXDATA)pCtrl->userdata; |
return pData->itemHeight; |
break; |
|
case LB_SETITEMHEIGHT: |
pData = (PLISTBOXDATA)pCtrl->userdata; |
if (pData->itemHeight != LOWORD (lParam)) { |
RECT rcClient; |
|
pData->itemHeight = LOWORD (lParam); |
GetClientRect (hwnd, &rcClient); |
lstCalcParams (&rcClient, pData); |
|
lstSetVScrollInfo (hwnd, pData, TRUE); |
InvalidateRect (hwnd, NULL, TRUE); |
} |
break; |
|
case WM_SETFOCUS: |
{ |
pData = (PLISTBOXDATA)pCtrl->userdata; |
|
if (pData->dwFlags & LBF_FOCUS) |
break; |
|
pData->dwFlags |= LBF_FOCUS; |
InvalidateRect(hwnd, NULL, TRUE); |
|
NotifyParent (hwnd, pCtrl->id, LBN_SETFOCUS); |
} |
break; |
|
case WM_KILLFOCUS: |
{ |
pData = (PLISTBOXDATA)pCtrl->userdata; |
|
pData->dwFlags &= ~LBF_FOCUS; |
InvalidateRect(hwnd, NULL, TRUE); |
|
NotifyParent (hwnd, pCtrl->id, LBN_KILLFOCUS); |
} |
break; |
|
case WM_GETDLGCODE: |
return DLGC_WANTARROWS | DLGC_WANTCHARS; |
|
case WM_GETTEXTLENGTH: |
case WM_GETTEXT: |
case WM_SETTEXT: |
return -1; |
#if 0 |
case WM_SETFONT: |
break; |
|
case WM_GETFONT: |
break; |
#endif |
case WM_NCCALCSIZE: |
{ |
LPNCCALCSIZE_PARAMS lpnc; |
|
/* calculate client rect from passed window rect in rgrc[0]*/ |
lpnc = (LPNCCALCSIZE_PARAMS)lParam; |
if(GetWindowLong(hwnd, GWL_STYLE) & WS_BORDER) |
InflateRect(&lpnc->rgrc[0], -2, -2); |
} |
break; |
|
case WM_NCPAINT: |
{ |
RECT rc; |
|
hdc = wParam? (HDC)wParam: GetWindowDC (hwnd); |
GetWindowRect(hwnd, &rc); |
|
if (dwStyle & WS_BORDER) |
Draw3dInset(hdc, rc.left, rc.top, |
rc.right-rc.left, rc.bottom-rc.top); |
|
if (!wParam) |
ReleaseDC (hwnd, hdc); |
} |
break; |
|
case WM_PAINT: |
{ |
RECT rc; |
PAINTSTRUCT ps; |
|
hdc = BeginPaint (hwnd,&ps); |
pData = (PLISTBOXDATA)pCtrl->userdata; |
|
/* |
* If this is the first paint and there's nothing |
* selected, then auto select the topmost displayed item. |
*/ |
if (pData->dwFlags & LBF_NOTHINGSELECTED) { |
lstSelectItem (hwnd->style, pData, pData->itemTop); |
pData->dwFlags &= ~LBF_NOTHINGSELECTED; |
} |
GetClientRect (hwnd, &rc); |
lstOnDrawSListBoxItems (hdc, dwStyle, pData, rc.right-rc.left); |
lstDrawFocusRect (hdc, pData, &rc); |
|
EndPaint (hwnd, &ps); |
} |
break; |
|
case WM_LBUTTONDBLCLK: |
if (dwStyle & LBS_NOTIFY) |
NotifyParent (hwnd, pCtrl->id, LBN_DBLCLK); |
break; |
|
case WM_LBUTTONDOWN: |
{ |
int oldSel, mouseX, mouseY, hit; |
RECT rcInv; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
if (pData->itemCount == 0) |
break; |
|
mouseX = LOWORD (lParam); |
mouseY = HIWORD (lParam); |
hit = mouseY / pData->itemHeight; |
hit += pData->itemTop; |
|
if (hit >= pData->itemCount) |
break; |
|
GetClientRect (hwnd, &rcInv); |
oldSel = lstSelectItem (dwStyle, pData, hit); |
if ((dwStyle & LBS_NOTIFY) && (oldSel != hit)) |
NotifyParent (hwnd, pCtrl->id, LBN_SELCHANGE); |
if (oldSel >= 0) { |
if (oldSel >= pData->itemTop |
&& (oldSel <= pData->itemTop + pData->itemVisibles)) { |
lstGetItemsRect (pData, oldSel, oldSel, &rcInv); |
InvalidateRect (hwnd, &rcInv, TRUE); |
} |
} |
|
lstGetItemsRect (pData, hit, hit, &rcInv); |
InvalidateRect (hwnd, &rcInv, TRUE); |
|
if (pData->itemHilighted != hit) |
{ |
hdc = GetDC(hwnd); /* hdc = GetClientDC (hwnd); */ |
|
lstDrawFocusRect (hdc, pData, &rcInv); |
ReleaseDC (hwnd,hdc); |
} |
pData->itemHilighted = hit; |
|
if (dwStyle & LBS_CHECKBOX) { |
if (mouseX > 0 && mouseX < LST_WIDTH_CHECKMARK) { |
NotifyParent (hwnd, pCtrl->id, LBN_CLICKCHECKMARK); |
|
if (dwStyle & LBS_AUTOCHECK) { |
PLISTBOXITEM plbi; |
|
plbi = lstGetItem (pData, hit); |
|
switch (plbi->dwFlags & LBIF_CHECKMARKMASK) { |
case LBIF_CHECKED: |
plbi->dwFlags &= ~LBIF_CHECKMARKMASK; |
break; |
default: |
plbi->dwFlags &= ~LBIF_CHECKMARKMASK; |
plbi->dwFlags |= LBIF_CHECKED; |
break; |
} |
|
lstInvalidateItem (hwnd, pData, hit, TRUE); |
} |
} |
} |
|
lstSetVScrollInfo (hwnd, pData, TRUE); |
} |
break; |
|
case WM_LBUTTONUP: |
break; |
|
case WM_MOUSEMOVE: |
break; |
|
case WM_KEYDOWN: |
{ |
int oldSel, newSel, newTop; |
RECT rcInv; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
newTop = pData->itemTop; |
newSel = pData->itemHilighted; |
switch (LOWORD (wParam)) |
{ |
case VK_HOME: /* SCANCODE_HOME: */ |
newSel = 0; |
newTop = 0; |
break; |
|
case VK_END: /* SCANCODE_END: */ |
newSel = pData->itemCount - 1; |
if (pData->itemCount > pData->itemVisibles) |
newTop = pData->itemCount - pData->itemVisibles; |
else |
newTop = 0; |
break; |
|
case VK_DOWN: /* SCANCODE_CURSORBLOCKDOWN: */ |
newSel ++; |
if (newSel >= pData->itemCount) |
return 0; |
if (newSel > ITEM_BOTTOM (pData)) |
newTop ++; |
break; |
|
case VK_UP: /* SCANCODE_CURSORBLOCKUP: */ |
newSel --; |
if (newSel < 0) |
return 0; |
if (newSel < pData->itemTop) |
newTop --; |
break; |
|
case VK_NEXT: /* SCANCODE_PAGEDOWN: */ |
newSel += pData->itemVisibles; |
if (newSel >= pData->itemCount) |
newSel = pData->itemCount - 1; |
|
if (pData->itemCount - newSel >= pData->itemVisibles) |
newTop = newSel; |
else |
newTop = max (pData->itemCount-pData->itemVisibles, 0); |
break; |
|
case VK_PRIOR: /* SCANCODE_PAGEUP: */ |
newSel -= pData->itemVisibles; |
if (newSel < 0) |
newSel = 0; |
|
newTop -= pData->itemVisibles; |
if (newTop < 0) |
newTop = 0; |
break; |
|
default: |
return 0; |
} |
|
GetClientRect (hwnd, &rcInv); |
if (pData->itemHilighted != newSel) { |
if (pData->itemTop != newTop) { |
pData->itemTop = newTop; |
pData->itemHilighted = newSel; |
if (!(dwStyle & LBS_MULTIPLESEL)) { |
oldSel = lstSelectItem (dwStyle, pData, newSel); |
if ((dwStyle & LBS_NOTIFY) && (oldSel != newSel)) |
NotifyParent (hwnd, pCtrl->id, LBN_SELCHANGE); |
} |
InvalidateRect (hwnd, NULL, TRUE); |
} |
else { |
if (!(dwStyle & LBS_MULTIPLESEL)) { |
oldSel = lstSelectItem (dwStyle, pData, newSel); |
if ((dwStyle & LBS_NOTIFY) && (oldSel != newSel)) |
NotifyParent (hwnd, pCtrl->id, LBN_SELCHANGE); |
if (oldSel >= 0) { |
if (oldSel >= pData->itemTop |
&& oldSel <= (ITEM_BOTTOM (pData) + 1)) { |
lstGetItemsRect (pData, oldSel, oldSel, &rcInv); |
InvalidateRect (hwnd, &rcInv, TRUE); |
} |
} |
|
if (newSel < newTop) { |
pData->itemHilighted = newSel; |
break; |
} |
|
lstGetItemsRect (pData, pData->itemHilighted, |
pData->itemHilighted, &rcInv); |
|
hdc = GetDC(hwnd); /* hdc = GetClientDC (hwnd); */ |
|
lstDrawFocusRect (hdc, pData, &rcInv); |
ReleaseDC (hwnd,hdc); |
|
pData->itemHilighted = newSel; |
lstGetItemsRect (pData, newSel, newSel, &rcInv); |
InvalidateRect (hwnd, &rcInv, TRUE); |
} |
else |
{ |
hdc = GetDC(hwnd); /* hdc = GetClientDC (hwnd); */ |
|
lstDrawFocusRect (hdc, pData, &rcInv); |
pData->itemHilighted = newSel; |
GetClientRect (hwnd, &rcInv); |
lstDrawFocusRect (hdc, pData, &rcInv); |
ReleaseDC (hwnd,hdc); |
} |
} |
lstSetVScrollInfo (hwnd, pData, TRUE); |
} |
} |
break; |
|
case WM_CHAR: |
{ |
char head [2]; |
int index; |
int newTop; |
|
head [0] = (char) (wParam); |
head [1] = '\0'; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
|
if (head[0] == ' ') { |
if (dwStyle & LBS_MULTIPLESEL) { |
RECT rcInv; |
|
GetClientRect (hwnd, &rcInv); |
lstSelectItem (dwStyle, pData, pData->itemHilighted); |
lstGetItemsRect (pData, |
pData->itemHilighted, |
pData->itemHilighted, |
&rcInv); |
InvalidateRect (hwnd, &rcInv, TRUE); |
} |
else if (dwStyle & LBS_CHECKBOX) { |
NotifyParent (hwnd, pCtrl->id, LBN_CLICKCHECKMARK); |
|
if (dwStyle & LBS_AUTOCHECK) { |
PLISTBOXITEM plbi; |
|
plbi = lstGetItem (pData, pData->itemHilighted); |
|
switch (plbi->dwFlags & LBIF_CHECKMARKMASK) { |
case LBIF_CHECKED: |
plbi->dwFlags &= ~LBIF_CHECKMARKMASK; |
break; |
default: |
plbi->dwFlags &= ~LBIF_CHECKMARKMASK; |
plbi->dwFlags |= LBIF_CHECKED; |
break; |
} |
|
lstInvalidateItem (hwnd, pData, |
pData->itemHilighted, TRUE); |
} |
} |
break; |
} |
|
index = lstFindItem (pData, pData->itemHilighted + 1, head, FALSE); |
if (index < 0) { |
index = lstFindItem (pData, 0, head, FALSE); |
} |
|
if (index >= 0) { |
if (pData->itemCount - index >= pData->itemVisibles) |
newTop = index; |
else |
newTop = max (pData->itemCount - pData->itemVisibles, 0); |
|
pData->itemTop = newTop; |
pData->itemHilighted = index; |
if (!(dwStyle & LBS_MULTIPLESEL)) |
lstSelectItem (dwStyle, pData, index); |
InvalidateRect (hwnd, NULL, TRUE); |
|
lstSetVScrollInfo (hwnd, pData, TRUE); |
} |
} |
break; |
|
case WM_VSCROLL: |
{ |
int newTop; |
int scrollHeight = 0; |
|
pData = (PLISTBOXDATA)pCtrl->userdata; |
newTop = pData->itemTop; |
switch(wParam) |
{ |
case SB_LINEDOWN: |
|
#if 0 /* test itemVisibles */ |
printf("itemVisibles:%d\n",pData->itemVisibles); |
printf("SB_LINEDOWN:(%d:%d)\n", |
ITEM_BOTTOM (pData),(pData->itemCount - 1 )); |
#endif |
if (ITEM_BOTTOM (pData) < (pData->itemCount - 1 )) |
{ |
newTop ++; |
scrollHeight = -pData->itemHeight; /* for ScrollWindow() */ |
} |
break; |
|
case SB_LINEUP: |
if (pData->itemTop > 0) |
{ |
newTop --; |
scrollHeight = pData->itemHeight; |
} |
break; |
|
case SB_PAGEDOWN: |
if ((pData->itemTop + (pData->itemVisibles << 1)) <= |
pData->itemCount) |
newTop += pData->itemVisibles; |
else |
newTop = pData->itemCount - pData->itemVisibles; |
|
if (newTop < 0) |
return 0; |
|
scrollHeight = -(newTop - pData->itemTop) |
*pData->itemHeight; |
break; |
|
case SB_PAGEUP: |
if (pData->itemTop >= pData->itemVisibles) |
newTop -= pData->itemVisibles; |
else |
newTop = 0; |
|
scrollHeight = (pData->itemTop - newTop)*pData->itemHeight; |
break; |
|
case SB_THUMBTRACK: |
newTop = (int)lParam; |
scrollHeight = (pData->itemTop - newTop)*pData->itemHeight; |
break; |
} |
|
if (scrollHeight) |
{ |
pData->itemTop = newTop; |
#if 0 /* !!: fix: no scroll */ |
ScrollWindow (hwnd, 0, scrollHeight, NULL, NULL); |
#endif |
SendMessage (hwnd, WM_PAINT, 0, 0); |
|
lstSetVScrollInfo (hwnd, pData, TRUE); |
|
return 0; |
} |
} |
break; |
|
case WM_HSCROLL: |
pData = (PLISTBOXDATA)pCtrl->userdata; |
switch (wParam) |
{ |
case SB_LINERIGHT: |
break; |
|
case SB_LINELEFT: |
break; |
|
case SB_PAGELEFT: |
break; |
|
case SB_PAGERIGHT: |
break; |
} |
break; |
|
default: |
return DefWindowProc (hwnd, message, wParam, lParam); |
} |
return 0; |
} |
/edit.c
0,0 → 1,1172
/* |
* Copyright (C) 1999, 2000, Wei Yongming. |
* Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com> |
* |
* Edit control for Microwindows win32 api. |
*/ |
|
/* |
** This library is free software; you can redistribute it and/or |
** modify it under the terms of the GNU Library General Public |
** License as published by the Free Software Foundation; either |
** version 2 of the License, or (at your option) any later version. |
** |
** This library is distributed in the hope that it will be useful, |
** but WITHOUT ANY WARRANTY; without even the implied warranty of |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
** Library General Public License for more details. |
** |
** You should have received a copy of the GNU Library General Public |
** License along with this library; if not, write to the Free |
** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
** MA 02111-1307, USA |
*/ |
|
/* |
** Alternatively, the contents of this file may be used under the terms |
** of the Mozilla Public License (the "MPL License") in which case the |
** provisions of the MPL License are applicable instead of those above. |
*/ |
|
/* Note: |
** Although there was a version by Zhao Jianghua, this version of |
** EDIT control is written by Wei Yongming from scratch. |
** |
** Create date: 1999/8/26 |
** |
** Modify records: |
** |
** Who When Where For What Status |
**----------------------------------------------------------------------------- |
** WEI Yongming 2000/02/24 Tsinghua Add MPL License Finished |
** Kevin Tseng 2000/05/30 gv port to microwin ported |
** Greg Haerr 2000/06/16 Utah 3d look, bug fixes Finished |
** Kevin Tseng 2000/06/22 gv port to mw-nanox ported |
** |
** TODO: |
** * Selection. |
** * Undo. |
*/ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#define MWINCLUDECOLORS |
#include "windows.h" /* windef.h, winuser.h */ |
#include "wintools.h" |
#include "device.h" /* GdGetTextSize */ |
|
#define USE_BIG5 |
|
#if 0 |
#define DEFAULT_FONT DEFAULT_GUI_FONT |
#endif |
#define DEFAULT_FONT SYSTEM_FIXED_FONT |
|
#define WIDTH_EDIT_BORDER 2 |
#define MARGIN_EDIT_LEFT 1 |
#define MARGIN_EDIT_TOP 1 |
#define MARGIN_EDIT_RIGHT 2 |
#define MARGIN_EDIT_BOTTOM 1 |
|
#define LEN_SLEDIT_BUFFER 3000 |
#define LEN_SLEDIT_UNDOBUFFER 1024 |
|
#define EST_FOCUSED 0x00000001L |
#define EST_MODIFY 0x00000002L |
#define EST_READONLY 0x00000004L |
#define EST_REPLACE 0x00000008L |
|
#define EDIT_OP_NONE 0x00 |
#define EDIT_OP_DELETE 0x01 |
#define EDIT_OP_INSERT 0x02 |
#define EDIT_OP_REPLACE 0x03 |
|
typedef struct tagSLEDITDATA { |
HFONT hFont; /* hFont used */ |
int bufferLen; /* length of buffer */ |
|
int dataEnd; /* data end position */ |
int editPos; /* current edit position */ |
int caretOff; /* caret offset in box */ |
int startPos; /* start display position */ |
|
int selStart; /* selection start position */ |
int selEnd; /* selection end position */ |
|
int passwdChar; /* password character */ |
|
int leftMargin; /* left margin */ |
int topMargin; /* top margin */ |
int rightMargin; /* right margin */ |
int bottomMargin; /* bottom margin */ |
|
int hardLimit; /* hard limit */ |
|
int lastOp; /* last operation */ |
int lastPos; /* last operation position */ |
int affectedLen; /* affected len of last operation */ |
int undoBufferLen; /* undo buffer len */ |
char undoBuffer [LEN_SLEDIT_UNDOBUFFER]; /* Undo buffer; */ |
char buffer [LEN_SLEDIT_BUFFER]; /* buffer */ |
} SLEDITDATA, *PSLEDITDATA; |
|
static LRESULT CALLBACK |
SLEditCtrlProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); |
|
static int GetSysCharHeight (HWND hwnd) |
{ |
#ifndef USE_BIG5 |
HDC hdc; |
int xw, xh, xb; |
|
hdc = GetDC(hwnd); |
SelectObject(hdc, GetStockObject(DEFAULT_FONT)); |
GdSetFont(hdc->font->pfont); |
GdGetTextSize(hdc->font->pfont,"X",1, &xw,&xh,&xb,MWTF_ASCII); |
ReleaseDC(hwnd,hdc); |
|
return xh; |
#else |
return 12; |
#endif |
} |
|
static int GetSysCharWidth (HWND hwnd) |
{ |
#ifndef USE_BIG5 |
HDC hdc; |
int xw, xh, xb; |
|
hdc = GetDC(hwnd); |
SelectObject(hdc, GetStockObject(DEFAULT_FONT)); |
GdSetFont(hdc->font->pfont); |
GdGetTextSize(hdc->font->pfont,"X",1, &xw,&xh,&xb,MWTF_ASCII); |
ReleaseDC(hwnd,hdc); |
|
return xw; |
#else |
return 6; |
#endif |
} |
|
static int GetSysCCharWidth (HWND hwnd) |
{ |
return (2*GetSysCharWidth(hwnd)); |
} |
|
int WINAPI MwRegisterEditControl(HINSTANCE hInstance) |
{ |
WNDCLASS wc; |
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; |
wc.lpfnWndProc = (WNDPROC)SLEditCtrlProc; |
wc.cbClsExtra = 0; |
wc.cbWndExtra = 0; |
wc.hInstance = hInstance; |
wc.hIcon = NULL; |
wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/ |
wc.hbrBackground= GetStockObject(WHITE_BRUSH); |
wc.lpszMenuName = NULL; |
wc.lpszClassName= "EDIT"; |
|
return RegisterClass(&wc); |
} |
|
static int edtGetOutWidth (const HWND pCtrl) |
{ |
return pCtrl->clirect.right - pCtrl->clirect.left |
- ((PSLEDITDATA)(pCtrl->userdata2))->leftMargin |
- ((PSLEDITDATA)(pCtrl->userdata2))->rightMargin; |
} |
|
static int edtGetStartDispPosAtEnd (const HWND pCtrl, PSLEDITDATA pSLEditData) |
{ |
int nOutWidth = edtGetOutWidth (pCtrl); |
int endPos = pSLEditData->dataEnd; |
int newStartPos = pSLEditData->startPos; |
const char* buffer = pSLEditData->buffer; |
|
while (TRUE) { |
if ((endPos - newStartPos) * GetSysCharWidth (pCtrl) < nOutWidth) |
break; |
|
/* FIXME: #ifdef GB2312?*/ |
if ((BYTE)buffer [newStartPos] > 0xA0) /* 1st:gb:a1-f7,big5:a1-f9 */ |
{ |
newStartPos ++; |
if (newStartPos < pSLEditData->dataEnd) |
{ |
#ifndef USE_BIG5 |
if ((BYTE)buffer [newStartPos] > 0xA0) |
#else /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
if ( ((BYTE)buffer [newStartPos] >= 0x40 && (BYTE)buffer[newStartPos] <= 0x7e) || |
((BYTE)buffer [newStartPos] >= 0xa1 && (BYTE)buffer[newStartPos] <= 0xfe)) |
#endif |
newStartPos ++; |
} |
} |
else |
newStartPos ++; |
} |
|
return newStartPos; |
} |
|
static int edtGetDispLen (const HWND pCtrl) |
{ |
int i, n = 0; |
int nOutWidth = edtGetOutWidth (pCtrl); |
int nTextWidth = 0; |
PSLEDITDATA pSLEditData = (PSLEDITDATA)(pCtrl->userdata2); |
const char* buffer = pSLEditData->buffer; |
|
for (i = pSLEditData->startPos; i < pSLEditData->dataEnd; i++) { |
/* FIXME #ifdef GB2312?*/ |
if ((BYTE)buffer [i] > 0xA0) /* st:gb:a1-f7,big5:a1-f9 */ |
{ |
i++; |
if (i < pSLEditData->dataEnd) |
{ |
#ifndef USE_BIG5 |
if ((BYTE)buffer [i] > 0xA0) /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
#else /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
if ( ((BYTE)buffer [i] >= 0x40 && (BYTE)buffer[i] <= 0x7e) || |
((BYTE)buffer [i] >= 0xa1 && (BYTE)buffer[i] <= 0xfe)) |
#endif |
{ |
nTextWidth += GetSysCCharWidth (pCtrl); |
n += 2; |
} |
else |
i--; |
} |
else |
{ |
nTextWidth += GetSysCharWidth (pCtrl); |
n++; |
} |
} |
else |
{ |
nTextWidth += GetSysCharWidth (pCtrl); |
n++; |
} |
|
if (nTextWidth > nOutWidth) |
break; |
} |
|
return n; |
} |
|
static int edtGetOffset (HWND hwnd,const SLEDITDATA* pSLEditData, int x) |
{ |
int i; |
int newOff = 0; |
int nTextWidth = 0; |
const char* buffer = pSLEditData->buffer; |
|
x -= pSLEditData->leftMargin; |
for (i = pSLEditData->startPos; i < pSLEditData->dataEnd; i++) { |
if ((nTextWidth + (GetSysCharWidth(hwnd) >> 1)) >= x) |
break; |
|
/* FIXME #ifdef GB2312?*/ |
if ((BYTE)buffer [i] > 0xA0) /* 1st:gb:a1-f7,big5:a1-f9 */ |
{ |
i++; |
if (i < pSLEditData->dataEnd) |
{ |
#ifndef USE_BIG5 |
if ((BYTE)buffer [i] > 0xA0) /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
#else /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
if ( ((BYTE)buffer [i] >= 0x40 && (BYTE)buffer[i] <= 0x7e) || |
((BYTE)buffer [i] >= 0xa1 && (BYTE)buffer[i] <= 0xfe)) |
#endif |
{ |
nTextWidth += GetSysCCharWidth (hwnd); |
newOff += 2; |
} |
else |
i --; |
} |
else |
{ |
nTextWidth += GetSysCharWidth (hwnd); |
newOff ++; |
} |
} |
else |
{ |
nTextWidth += GetSysCharWidth (hwnd); |
newOff ++; |
} |
|
} |
|
return newOff; |
} |
|
static BOOL edtIsACCharBeforePosition (const char* string, int pos) |
{ |
if (pos < 2) |
return FALSE; |
|
/* 1st:gb:a1-f7,big5:a1-f9 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
#ifndef USE_BIG5 |
/* FIXME #ifdef GB2312?*/ |
if ((BYTE)string [pos - 2] > 0xA0 && (BYTE)string [pos - 1] > 0xA0) |
return TRUE; |
#else |
if ((BYTE)string [pos - 2] > 0xA0) |
{ |
if ( ((BYTE)string [pos - 1] >= 0x40 && (BYTE)string[pos - 1] <= 0x7e) || |
((BYTE)string [pos - 1] >= 0xa1 && (BYTE)string[pos - 1] <= 0xfe)) |
return TRUE; |
} |
#endif |
|
return FALSE; |
} |
|
static BOOL edtIsACCharAtPosition (const char* string, int len, int pos) |
{ |
if (pos > (len - 2)) |
return FALSE; |
|
/* 1st:gb:a1-f7,big5:a1-f9 2nd:gb:a1-fe,big5:40-7e,a1-fe */ |
#ifndef USE_BIG5 |
if ((BYTE)string [pos] > 0xA0 && (BYTE)string [pos + 1] > 0xA0) |
return TRUE; |
#else |
if ((BYTE)string [pos] > 0xA0) |
{ |
if ( ((BYTE)string [pos + 1] >= 0x40 && (BYTE)string [pos + 1] <= 0x7e) || |
((BYTE)string [pos + 1] >= 0xa1 && (BYTE)string [pos + 1] <= 0xfe)) { |
/*fprintf(stderr,"true\n"); |
fflush(stderr);*/ |
return TRUE; |
} |
} |
#endif |
|
return FALSE; |
} |
|
LRESULT CALLBACK |
SLEditCtrlProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
{ |
HWND pCtrl; |
DWORD dwStyle; |
HDC hdc; |
PSLEDITDATA pSLEditData; |
RECT rc; |
|
pCtrl = hWnd; |
dwStyle = pCtrl->style; |
|
switch (message) |
{ |
case WM_CREATE: |
if (!(pSLEditData = malloc (sizeof (SLEDITDATA)))) { |
fprintf (stderr, "EDIT: malloc error!\n"); |
return -1; |
} |
|
pSLEditData->hFont = GetStockObject(DEFAULT_FONT); |
|
pSLEditData->bufferLen = LEN_SLEDIT_BUFFER; |
pSLEditData->editPos = 0; |
pSLEditData->caretOff = 0; |
pSLEditData->startPos = 0; |
|
pSLEditData->selStart = 0; |
pSLEditData->selEnd = 0; |
pSLEditData->passwdChar = '*'; |
pSLEditData->leftMargin = MARGIN_EDIT_LEFT; |
pSLEditData->topMargin = MARGIN_EDIT_TOP; |
pSLEditData->rightMargin = MARGIN_EDIT_RIGHT; |
pSLEditData->bottomMargin = MARGIN_EDIT_BOTTOM; |
|
pSLEditData->hardLimit = -1; |
|
/* undo information */ |
pSLEditData->lastOp = EDIT_OP_NONE; |
pSLEditData->lastPos = 0; |
pSLEditData->affectedLen = 0; |
pSLEditData->undoBufferLen = LEN_SLEDIT_UNDOBUFFER; |
pSLEditData->undoBuffer [0] = '\0'; |
|
pSLEditData->dataEnd = strlen (pCtrl->szTitle); |
memcpy (pSLEditData->buffer, pCtrl->szTitle, |
min (LEN_SLEDIT_BUFFER, pSLEditData->dataEnd)); |
|
pCtrl->userdata2 = (DWORD) pSLEditData; |
|
pCtrl->userdata = 0; |
break; |
|
case WM_DESTROY: |
DestroyCaret (); |
|
free ((void*)pCtrl->userdata2); |
break; |
#if 0 |
case WM_CHANGESIZE: |
{ |
pCtrl->cl = pCtrl->left + WIDTH_EDIT_BORDER; |
pCtrl->ct = pCtrl->top + WIDTH_EDIT_BORDER; |
pCtrl->cr = pCtrl->right - WIDTH_EDIT_BORDER; |
pCtrl->cb = pCtrl->bottom - WIDTH_EDIT_BORDER; |
} |
break; |
#endif |
|
#if 1 /* jmt: for edit: chinese support */ |
case WM_SETFONT: |
{ |
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
pSLEditData->hFont = (HFONT)wParam; |
|
ShowWindow(hWnd, SW_HIDE); |
ShowWindow(hWnd, SW_SHOWNA); |
|
if(LOWORD(lParam)) |
InvalidateRect(hWnd,NULL,TRUE); |
} |
return (LRESULT)0; |
|
case WM_GETFONT: |
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
return (LRESULT)pSLEditData->hFont; |
#endif |
|
#if 0 |
case WM_SETCURSOR: |
if (dwStyle & WS_DISABLED) |
{ |
SetCursor (GetSystemCursor (IDC_ARROW)); |
return 0; |
} |
break; |
#endif |
case WM_KILLFOCUS: |
pCtrl->userdata &= ~EST_FOCUSED; |
|
HideCaret (hWnd); |
DestroyCaret (); |
|
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (pCtrl->id, EN_KILLFOCUS), (LPARAM)hWnd); |
break; |
|
case WM_SETFOCUS: |
if (pCtrl->userdata & EST_FOCUSED) |
return 0; |
|
pCtrl->userdata |= EST_FOCUSED; |
|
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
/* only implemented for ES_LEFT align format. */ |
|
CreateCaret (hWnd, NULL, 1 /*+ GetSysCharWidth(hWnd)*/, |
hWnd->clirect.bottom-hWnd->clirect.top-2); |
SetCaretPos (pSLEditData->caretOff * GetSysCharWidth (hWnd) |
+ pSLEditData->leftMargin, pSLEditData->topMargin); |
ShowCaret (hWnd); |
|
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (pCtrl->id, EN_SETFOCUS), (LPARAM) hWnd); |
break; |
|
case WM_ENABLE: |
if ( (!(dwStyle & WS_DISABLED) && !wParam) |
|| ((dwStyle & WS_DISABLED) && wParam) ) { |
if (wParam) |
pCtrl->style &= ~WS_DISABLED; |
else |
pCtrl->style |= WS_DISABLED; |
|
InvalidateRect (hWnd, NULL, FALSE); |
} |
break; |
|
case WM_NCCALCSIZE: |
{ |
LPNCCALCSIZE_PARAMS lpnc; |
|
/* calculate client rect from passed window rect in rgrc[0]*/ |
lpnc = (LPNCCALCSIZE_PARAMS)lParam; |
if(GetWindowLong(hWnd, GWL_STYLE) & WS_BORDER) |
InflateRect(&lpnc->rgrc[0], -2, -2); |
} |
break; |
|
case WM_NCPAINT: |
hdc = wParam? (HDC)wParam: GetWindowDC (hWnd); |
GetWindowRect(hWnd, &rc); |
|
if (dwStyle & WS_BORDER) |
Draw3dInset(hdc, rc.left, rc.top, |
rc.right-rc.left, rc.bottom-rc.top); |
|
if (!wParam) |
ReleaseDC (hWnd, hdc); |
break; |
|
case WM_PAINT: |
{ |
int dispLen; |
char* dispBuffer; |
RECT rect,rc; |
PAINTSTRUCT ps; |
|
HGDIOBJ oldfont; |
oldfont=NULL; |
|
hdc = BeginPaint (hWnd,&ps); |
GetClientRect (hWnd, &rect); |
|
if (dwStyle & WS_DISABLED) |
{ |
#if 0 |
SetBrushColor (hdc, LTGRAY/*COLOR_lightgray*/); |
FillBox (hdc, 0, 0, rect.right, rect.bottom); |
#else |
rc.left=0; rc.top=0; rc.bottom=rect.bottom; rc.right=rect.right; |
FillRect(hdc,&rc,GetStockObject(LTGRAY_BRUSH)); |
#endif |
SetBkColor (hdc, LTGRAY/*COLOR_lightgray*/); |
} |
else |
{ |
#if 0 |
SetBrushColor (hdc, WHITE/*COLOR_lightwhite*/); |
FillBox (hdc, 0, 0, rect.right, rect.bottom); |
#else |
rc.left=0; rc.top=0; rc.bottom=rect.bottom; rc.right=rect.right; |
FillRect(hdc,&rc,GetStockObject(WHITE_BRUSH)); |
#endif |
SetBkColor (hdc, WHITE/*COLOR_lightwhite*/); |
} |
|
SetTextColor (hdc, BLACK/*COLOR_black*/); |
dispLen = edtGetDispLen (pCtrl); |
if (dispLen == 0) |
{ |
EndPaint (hWnd, &ps); |
break; |
} |
|
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
|
#ifdef _DEBUG |
if (pSLEditData->startPos > pSLEditData->dataEnd) |
fprintf (stderr, "ASSERT failure: %s.\n", "Edit Paint"); |
#endif |
|
dispBuffer = ALLOCA(dispLen + 1); |
|
if (dwStyle & ES_PASSWORD) |
memset (dispBuffer, '*', dispLen); |
else |
memcpy (dispBuffer, |
pSLEditData->buffer + pSLEditData->startPos, |
dispLen); |
|
dispBuffer [dispLen] = '\0'; |
|
/* only implemented ES_LEFT align format for single line edit. */ |
rect.left += pSLEditData->leftMargin; |
rect.top += pSLEditData->topMargin; |
rect.right -= pSLEditData->rightMargin; |
rect.bottom -= pSLEditData->bottomMargin; |
|
#if 0 /* FIXME no ClipRectIntersect() */ |
#if 0 |
ClipRectIntersect (hdc, &rect); |
#else |
GdSetClipRects(hdc->psd,1,&rect); /*??==ClipRectIntersect??*/ |
#endif |
#endif |
|
#ifdef USE_BIG5 |
oldfont=SelectObject(hdc,CreateFont(12, |
0,0,0,0,0,0,0,0,0,0,0, |
FF_DONTCARE|DEFAULT_PITCH, |
"HZXFONT")); |
#else |
SelectObject(hdc, pSLEditData->hFont); |
#endif |
TextOut (hdc, pSLEditData->leftMargin, pSLEditData->topMargin, |
dispBuffer,-1); |
|
#ifdef USE_BIG5 |
DeleteObject(SelectObject(hdc,oldfont)); |
#endif |
|
EndPaint (hWnd, &ps); |
|
FREEA(dispBuffer); |
} |
break; |
#if 1 /* jmt+ */ |
case WM_KEYDOWN: |
{ |
BOOL bChange = FALSE; |
int i; |
RECT InvRect; |
int deleted; |
|
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
|
switch ((int)(wParam)) /* (LOWORD (wParam)) */ |
{ |
#if 0 |
case SCANCODE_ENTER: |
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (pCtrl->id, EN_ENTER), (LPARAM) hWnd); |
return 0; |
|
case SCANCODE_HOME: |
if (pSLEditData->editPos == 0) |
return 0; |
|
pSLEditData->editPos = 0; |
pSLEditData->caretOff = 0; |
|
SetCaretPos (pSLEditData->caretOff * GetSysCharWidth (hWnd) |
+ pSLEditData->leftMargin, pSLEditData->topMargin); |
if (pSLEditData->startPos != 0) |
InvalidateRect (hWnd, NULL, FALSE); |
|
pSLEditData->startPos = 0; |
return 0; |
|
case SCANCODE_END: |
{ |
int newStartPos; |
|
if (pSLEditData->editPos == pSLEditData->dataEnd) |
return 0; |
|
newStartPos = edtGetStartDispPosAtEnd (pCtrl, pSLEditData); |
|
pSLEditData->editPos = pSLEditData->dataEnd; |
pSLEditData->caretOff = pSLEditData->editPos - newStartPos; |
|
SetCaretPos (pSLEditData->caretOff * GetSysCharWidth (hWnd) |
+ pSLEditData->leftMargin, pSLEditData->topMargin); |
if (pSLEditData->startPos != newStartPos) |
InvalidateRect (hWnd, NULL, FALSE); |
|
pSLEditData->startPos = newStartPos; |
} |
return 0; |
#endif |
|
case VK_LEFT: /* SCANCODE_CURSORBLOCKLEFT: */ |
{ |
BOOL bScroll = FALSE; |
int scrollStep; |
|
if (pSLEditData->editPos == 0) |
return 0; |
|
if (edtIsACCharBeforePosition (pSLEditData->buffer, |
pSLEditData->editPos)) |
{ |
scrollStep = 2; |
pSLEditData->editPos -= 2; |
} |
else { |
scrollStep = 1; |
pSLEditData->editPos --; |
} |
|
pSLEditData->caretOff -= scrollStep; |
if (pSLEditData->caretOff == 0 |
&& pSLEditData->editPos != 0) |
{ |
bScroll = TRUE; |
|
if (edtIsACCharBeforePosition (pSLEditData->buffer, |
pSLEditData->editPos)) |
{ |
pSLEditData->startPos -= 2; |
pSLEditData->caretOff = 2; |
} |
else |
{ |
pSLEditData->startPos --; |
pSLEditData->caretOff = 1; |
} |
} |
else if (pSLEditData->caretOff < 0) |
{ |
pSLEditData->startPos = 0; |
pSLEditData->caretOff = 0; |
} |
|
SetCaretPos (pSLEditData->caretOff * GetSysCharWidth (hWnd) |
+ pSLEditData->leftMargin, pSLEditData->topMargin); |
|
if (bScroll) |
InvalidateRect (hWnd, NULL, FALSE); |
} |
return 0; |
|
case VK_RIGHT: /* SCANCODE_CURSORBLOCKRIGHT: */ |
{ |
BOOL bScroll = FALSE; |
int scrollStep, moveStep; |
|
if (pSLEditData->editPos == pSLEditData->dataEnd) |
return 0; |
|
if (edtIsACCharAtPosition (pSLEditData->buffer, |
pSLEditData->dataEnd, |
pSLEditData->startPos)) |
{ |
if (edtIsACCharAtPosition (pSLEditData->buffer, |
pSLEditData->dataEnd, |
pSLEditData->editPos)) |
{ |
scrollStep = 2; |
moveStep = 2; |
pSLEditData->editPos += 2; |
} |
else |
{ |
scrollStep = 2; |
moveStep = 1; |
pSLEditData->editPos ++; |
} |
} |
else |
{ |
if (edtIsACCharAtPosition (pSLEditData->buffer, |
pSLEditData->dataEnd, |
pSLEditData->editPos)) |
{ |
if (edtIsACCharAtPosition (pSLEditData->buffer, |
pSLEditData->dataEnd, |
pSLEditData->startPos + 1)) |
scrollStep = 3; |
else |
scrollStep = 2; |
|
moveStep = 2; |
pSLEditData->editPos += 2; |
} |
else |
{ |
scrollStep = 1; |
moveStep = 1; |
pSLEditData->editPos ++; |
} |
} |
|
pSLEditData->caretOff += moveStep; |
if (pSLEditData->caretOff * GetSysCharWidth (hWnd) |
> edtGetOutWidth (pCtrl)) |
{ |
bScroll = TRUE; |
pSLEditData->startPos += scrollStep; |
|
pSLEditData->caretOff = |
pSLEditData->editPos - pSLEditData->startPos; |
} |
|
SetCaretPos (pSLEditData->caretOff * GetSysCharWidth (hWnd) |
+ pSLEditData->leftMargin, pSLEditData->topMargin); |
if (bScroll) |
InvalidateRect (hWnd, NULL, FALSE); |
} |
return 0; |
#if 0 |
case SCANCODE_INSERT: |
pCtrl->userdata ^= EST_REPLACE; |
break; |
#endif |
case VK_DELETE: /* SCANCODE_REMOVE: */ |
if ((pCtrl->userdata & EST_READONLY) |
|| (pSLEditData->editPos == pSLEditData->dataEnd)){ |
#if 0 /* fix: no ping() */ |
Ping (); |
#endif |
return 0; |
} |
|
if (edtIsACCharAtPosition (pSLEditData->buffer, |
pSLEditData->dataEnd, pSLEditData->editPos)) |
deleted = 2; |
else |
deleted = 1; |
|
for (i = pSLEditData->editPos; |
i < pSLEditData->dataEnd - deleted; i++) |
pSLEditData->buffer [i] |
= pSLEditData->buffer [i + deleted]; |
|
pSLEditData->dataEnd -= deleted; |
bChange = TRUE; |
|
InvRect.left = pSLEditData->leftMargin |
+ pSLEditData->caretOff * GetSysCharWidth (hWnd); |
InvRect.top = pSLEditData->topMargin; |
InvRect.right = pCtrl->clirect.right - pCtrl->clirect.left; |
InvRect.bottom = pCtrl->clirect.bottom - pCtrl->clirect.top; |
|
InvalidateRect (hWnd, &InvRect, FALSE); |
break; |
|
case VK_BACK: /* SCANCODE_BACKSPACE: */ |
if ((pCtrl->userdata & EST_READONLY) |
|| (pSLEditData->editPos == 0)) { |
#if 0 /* fix: no ping */ |
Ping (); |
#endif |
return 0; |
} |
|
if (edtIsACCharBeforePosition (pSLEditData->buffer, |
pSLEditData->editPos)) |
deleted = 2; |
else |
deleted = 1; |
|
for (i = pSLEditData->editPos; |
i < pSLEditData->dataEnd; |
i++) |
pSLEditData->buffer [i - deleted] |
= pSLEditData->buffer [i]; |
|
pSLEditData->dataEnd -= deleted; |
pSLEditData->editPos -= deleted; |
bChange = TRUE; |
|
pSLEditData->caretOff -= deleted; |
if (pSLEditData->caretOff == 0 |
&& pSLEditData->editPos != 0) { |
if (edtIsACCharBeforePosition (pSLEditData->buffer, |
pSLEditData->editPos)) { |
pSLEditData->startPos -= 2; |
pSLEditData->caretOff = 2; |
} |
else { |
pSLEditData->startPos --; |
pSLEditData->caretOff = 1; |
} |
|
InvRect.left = pSLEditData->leftMargin; |
InvRect.top = pSLEditData->topMargin; |
InvRect.right = pCtrl->clirect.right - |
pCtrl->clirect.left; |
InvRect.bottom = pCtrl->clirect.bottom - |
pCtrl->clirect.top; |
} |
else { |
InvRect.left = pSLEditData->leftMargin |
+ pSLEditData->caretOff * GetSysCharWidth (hWnd); |
InvRect.top = pSLEditData->topMargin; |
InvRect.right = pCtrl->clirect.right - |
pCtrl->clirect.left; |
InvRect.bottom = pCtrl->clirect.bottom - |
pCtrl->clirect.top; |
} |
|
SetCaretPos (pSLEditData->caretOff * GetSysCharWidth (hWnd) |
+ pSLEditData->leftMargin, pSLEditData->topMargin); |
InvalidateRect (hWnd, &InvRect, FALSE); |
break; |
|
default: |
break; |
} |
|
if (bChange) |
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (pCtrl->id, EN_CHANGE), (LPARAM) hWnd); |
} |
break; |
#endif |
case WM_CHAR: |
{ |
char charBuffer [2]; |
int i, chars, scrollStep, inserting; |
RECT InvRect; |
|
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
|
if (dwStyle & ES_READONLY) { |
|
#if 0 /* fix: no ping() */ |
Ping(); |
#endif |
return 0; |
} |
|
if (HIBYTE (wParam)) { |
charBuffer [0] = LOBYTE (wParam); |
charBuffer [1] = HIBYTE (wParam); |
chars = 2; |
} |
else { |
charBuffer [0] = LOBYTE (wParam); |
chars = 1; |
} |
|
if (chars == 1) { |
switch (charBuffer [0]) |
{ |
case 0x00: /* NULL */ |
case 0x07: /* BEL */ |
case 0x08: /* BS */ |
case 0x09: /* HT */ |
case 0x0A: /* LF */ |
case 0x0B: /* VT */ |
case 0x0C: /* FF */ |
case 0x0D: /* CR */ |
case 0x1B: /* Escape */ |
return 0; |
} |
} |
|
if (pCtrl->userdata & EST_REPLACE) { |
if (pSLEditData->dataEnd == pSLEditData->editPos) |
inserting = chars; |
else if (edtIsACCharAtPosition (pSLEditData->buffer, |
pSLEditData->dataEnd, |
pSLEditData->editPos)) { |
if (chars == 2) |
inserting = 0; |
else |
inserting = -1; |
} |
else { |
if (chars == 2) |
inserting = 1; |
else |
inserting = 0; |
} |
} |
else |
inserting = chars; |
|
/* check space */ |
if (pSLEditData->dataEnd + inserting > pSLEditData->bufferLen) { |
|
#if 0 /* fix: no ping() */ |
Ping (); |
#endif |
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (pCtrl->id, EN_MAXTEXT), (LPARAM) hWnd); |
return 0; |
} |
else if ((pSLEditData->hardLimit >= 0) |
&& ((pSLEditData->dataEnd + inserting) |
> pSLEditData->hardLimit)) { |
#if 0 /* fix: no ping() */ |
Ping (); |
#endif |
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (pCtrl->id, EN_MAXTEXT), (LPARAM) hWnd); |
return 0; |
} |
|
if (inserting == -1) { |
for (i = pSLEditData->editPos; i < pSLEditData->dataEnd-1; i++) |
pSLEditData->buffer [i] = pSLEditData->buffer [i + 1]; |
} |
else if (inserting > 0) { |
for (i = pSLEditData->dataEnd + inserting - 1; |
i > pSLEditData->editPos + inserting - 1; |
i--) |
pSLEditData->buffer [i] |
= pSLEditData->buffer [i - inserting]; |
} |
|
for (i = 0; i < chars; i++) |
pSLEditData->buffer [pSLEditData->editPos + i] |
= charBuffer [i]; |
|
pSLEditData->editPos += chars; |
pSLEditData->caretOff += chars; |
pSLEditData->dataEnd += inserting; |
|
if (pSLEditData->caretOff * GetSysCharWidth (hWnd) |
> edtGetOutWidth (pCtrl)) |
{ |
if (edtIsACCharAtPosition (pSLEditData->buffer, |
pSLEditData->dataEnd, |
pSLEditData->startPos)) |
scrollStep = 2; |
else { |
if (chars == 2) { |
if (edtIsACCharAtPosition (pSLEditData->buffer, |
pSLEditData->dataEnd, |
pSLEditData->startPos + 1)) |
scrollStep = 3; |
else |
scrollStep = 2; |
} |
else |
scrollStep = 1; |
} |
|
pSLEditData->startPos += scrollStep; |
|
pSLEditData->caretOff = |
pSLEditData->editPos - pSLEditData->startPos; |
|
InvRect.left = pSLEditData->leftMargin; |
InvRect.top = pSLEditData->topMargin; |
InvRect.right = pCtrl->clirect.right - pCtrl->clirect.left; |
InvRect.bottom = pCtrl->clirect.bottom - pCtrl->clirect.top; |
} |
else { |
InvRect.left = pSLEditData->leftMargin |
+ (pSLEditData->caretOff - chars) |
* GetSysCharWidth (hWnd); |
InvRect.top = pSLEditData->topMargin; |
InvRect.right = pCtrl->clirect.right - pCtrl->clirect.left; |
InvRect.bottom = pCtrl->clirect.bottom - pCtrl->clirect.top; |
} |
|
SetCaretPos (pSLEditData->caretOff * GetSysCharWidth (hWnd) |
+ pSLEditData->leftMargin, pSLEditData->topMargin); |
InvalidateRect (hWnd, &InvRect, FALSE); |
|
SendMessage (GetParent (hWnd), WM_COMMAND, |
(WPARAM) MAKELONG (pCtrl->id, EN_CHANGE), (LPARAM) hWnd); |
} |
break; |
|
case WM_GETTEXTLENGTH: |
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
return pSLEditData->dataEnd; |
|
case WM_GETTEXT: |
{ |
char* buffer = (char*)lParam; |
int len; |
|
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
|
len = min ((int)wParam, pSLEditData->dataEnd); |
|
memcpy (buffer, pSLEditData->buffer, len); |
buffer [len] = '\0'; |
|
return len; |
} |
break; |
|
case WM_SETTEXT: |
{ |
int len; |
|
if (dwStyle & ES_READONLY) |
return 0; |
|
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
|
|
len = strlen ((char*)lParam); |
len = min (len, pSLEditData->bufferLen); |
|
if (pSLEditData->hardLimit >= 0) |
len = min (len, pSLEditData->hardLimit); |
|
pSLEditData->dataEnd = len; |
memcpy (pSLEditData->buffer, (char*)lParam, len); |
|
pSLEditData->editPos = 0; |
pSLEditData->caretOff = 0; |
pSLEditData->startPos = 0; |
|
InvalidateRect (hWnd, NULL, FALSE); |
} |
break; |
|
case WM_LBUTTONDBLCLK: |
break; |
|
case WM_LBUTTONDOWN: |
{ |
int newOff; |
|
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
newOff = edtGetOffset (hWnd,pSLEditData, LOWORD (lParam)); |
|
if (newOff != pSLEditData->caretOff) |
{ |
pSLEditData->editPos += newOff - pSLEditData->caretOff; |
pSLEditData->caretOff = newOff; |
|
SetCaretPos (pSLEditData->caretOff * GetSysCharWidth (hWnd) |
+ pSLEditData->leftMargin, pSLEditData->topMargin); |
} |
} |
break; |
|
case WM_LBUTTONUP: |
break; |
|
case WM_MOUSEMOVE: |
break; |
|
case WM_GETDLGCODE: |
return DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS; |
|
case EM_SETREADONLY: |
if (wParam) |
pCtrl->style/*dwStyle*/ |= ES_READONLY; |
else |
pCtrl->style/*dwStyle*/ &= ~ES_READONLY; |
return 0; |
|
case EM_SETPASSWORDCHAR: |
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
|
if (pSLEditData->passwdChar != (int)wParam) { |
if (dwStyle & ES_PASSWORD) { |
pSLEditData->passwdChar = (int)wParam; |
InvalidateRect (hWnd, NULL, TRUE); |
} |
} |
return 0; |
|
case EM_GETPASSWORDCHAR: |
{ |
int* passwdchar; |
|
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
passwdchar = (int*) lParam; |
|
*passwdchar = pSLEditData->passwdChar; |
} |
return 0; |
|
case EM_LIMITTEXT: |
{ |
int newLimit = (int)wParam; |
|
if (newLimit >= 0) { |
pSLEditData = (PSLEDITDATA) (pCtrl->userdata2); |
if (pSLEditData->bufferLen < newLimit) |
pSLEditData->hardLimit = -1; |
else |
pSLEditData->hardLimit = newLimit; |
} |
} |
return 0; |
|
default: |
return DefWindowProc (hWnd, message, wParam, lParam); |
break; |
} |
return 0; |
} |
/static.c
0,0 → 1,369
/* |
* Copyright (C) 1999, 2000, Wei Yongming. |
* Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com> |
* |
* Static control for Microwindows win32 api. |
*/ |
|
/* |
** This library is free software; you can redistribute it and/or |
** modify it under the terms of the GNU Library General Public |
** License as published by the Free Software Foundation; either |
** version 2 of the License, or (at your option) any later version. |
** |
** This library is distributed in the hope that it will be useful, |
** but WITHOUT ANY WARRANTY; without even the implied warranty of |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
** Library General Public License for more details. |
** |
** You should have received a copy of the GNU Library General Public |
** License along with this library; if not, write to the Free |
** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
** MA 02111-1307, USA |
*/ |
|
/* |
** Alternatively, the contents of this file may be used under the terms |
** of the Mozilla Public License (the "MPL License") in which case the |
** provisions of the MPL License are applicable instead of those above. |
*/ |
|
/* Create date: 1999/5/22 |
** |
** Modify records: |
** |
** Who When Where For What Status |
**----------------------------------------------------------------------------- |
** WEI Yongming 1999/8/21 Tsinghua Rearrangment Finished |
** WEI Yongming 1999/10/27 Tsinghua SETTEXT bug Finished |
** WEI Yongming 1999/10/27 Tsinghua SETTEXT bug Finished |
** WEI Yongming 2000/02/24 Tsinghua Add MPL License Finished |
** Kevin Tseng 2000/06/26 gv port to microwin ported |
** Greg Haerr 2000/07/05 Utah bug fixes Finished |
*/ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#define MWINCLUDECOLORS |
#include "windows.h" /* windef.h, winuser.h */ |
#include "wintools.h" |
#include "device.h" /* GdGetTextSize */ |
|
/* jmt: should be SYSTEM_FIXED_FONT because of minigui's GetSysCharXXX() */ |
#define FONT_NAME SYSTEM_FIXED_FONT /* was DEFAULT_GUI_FONT*/ |
|
static LRESULT CALLBACK |
StaticControlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); |
|
int WINAPI MwRegisterStaticControl(HINSTANCE hInstance) |
{ |
WNDCLASS wc; |
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; |
wc.lpfnWndProc = (WNDPROC)StaticControlProc; |
wc.cbClsExtra = 0; |
wc.cbWndExtra = 0; |
wc.hInstance = hInstance; |
wc.hIcon = NULL; |
wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/ |
wc.hbrBackground= GetStockObject(WHITE_BRUSH); |
wc.lpszMenuName = NULL; |
wc.lpszClassName= "STATIC"; |
|
return RegisterClass(&wc); |
} |
|
#if 1 |
#define RECTW(rc) (rc.right-rc.left) |
#define RECTH(rc) (rc.bottom-rc.top) |
|
static DWORD GetWindowStyle (HWND hwnd) |
{ |
return hwnd->style; |
} |
|
static COLORREF GetWindowBkColor (HWND hwnd) |
{ |
MWBRUSHOBJ *hbr; |
hbr=(MWBRUSHOBJ *)hwnd->pClass->hbrBackground; |
return hbr->color; |
} |
|
static char *GetWindowCaption (HWND hwnd) |
{ |
return hwnd->szTitle; |
} |
|
static void SetWindowCaption (HWND hwnd,char *caption) |
{ |
if (strlen(caption)<=63) /* mw: szTitle[64] */ |
strcpy(hwnd->szTitle,caption); |
else |
{ |
strncpy(hwnd->szTitle,caption,63); |
hwnd->szTitle[63]='\0'; |
} |
} |
|
static int GetSysCharHeight (HWND hwnd) |
{ |
HDC hdc; |
int xw, xh, xb; |
|
hdc = GetDC(hwnd); |
|
SelectObject(hdc, GetStockObject(FONT_NAME)); |
|
#if MWCLIENT /* nanox client */ |
GrGetGCTextSize(hdc->gc, "X", 1, MWTF_ASCII, &xw, &xh, &xb); |
#else |
GdGetTextSize(hdc->font->pfont,"X",1, &xw,&xh,&xb,MWTF_ASCII); |
#endif |
ReleaseDC(hwnd,hdc); |
|
return xh; |
} |
|
static int GetSysCharWidth (HWND hwnd) |
{ |
HDC hdc; |
int xw, xh, xb; |
|
hdc = GetDC(hwnd); |
|
SelectObject(hdc, GetStockObject(FONT_NAME)); |
|
#if MWCLIENT /* nanox client */ |
GrGetGCTextSize(hdc->gc, "X", 1, MWTF_ASCII, &xw, &xh, &xb); |
#else |
GdGetTextSize(hdc->font->pfont,"X",1, &xw,&xh,&xb,MWTF_ASCII); |
#endif |
ReleaseDC(hwnd,hdc); |
|
return xw; |
} |
#endif |
|
static LRESULT CALLBACK |
StaticControlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) |
{ |
RECT rcClient; |
HDC hdc; |
char* spCaption; |
HWND pCtrl; |
UINT uFormat; |
DWORD dwStyle; |
|
pCtrl = hwnd; |
switch (message) { |
case WM_CREATE: |
return 0; |
|
case WM_DESTROY: |
break; |
|
case STM_GETIMAGE: |
return (int)(pCtrl->userdata); |
|
case STM_SETIMAGE: |
{ |
int pOldValue; |
|
pOldValue = (int)(pCtrl->userdata); |
pCtrl->userdata = (DWORD)wParam; |
InvalidateRect (hwnd, NULL, FALSE); |
return pOldValue; |
} |
|
case WM_GETDLGCODE: |
return DLGC_STATIC; |
|
|
case WM_PAINT: |
{ |
PAINTSTRUCT ps; |
RECT rc; |
HBRUSH hbr; |
|
hdc = BeginPaint (hwnd,&ps); |
|
GetClientRect (hwnd, &rcClient); |
|
FastFillRect(hdc, &rcClient, GetSysColor(COLOR_BTNFACE)); |
|
dwStyle = GetWindowStyle (hwnd); |
|
switch (dwStyle & SS_TYPEMASK) |
{ |
case SS_GRAYRECT: |
#if 0 |
SetBrushColor (hdc, LTGRAY); |
FillBox(hdc, 0, 0, RECTW(rcClient), RECTH(rcClient)); |
#else |
rc.left=0; rc.top=0; rc.bottom=RECTH(rcClient); rc.right=RECTW(rcClient); |
FillRect(hdc,&rc,GetStockObject(LTGRAY_BRUSH)); |
#endif |
break; |
|
case SS_GRAYFRAME: |
#if 0 |
Draw3DDownFrame (hdc, |
0, 0, rcClient.right, rcClient.bottom, |
DKGRAY); |
#else |
Draw3dInset(hdc, 0, 0, |
rcClient.right, rcClient.bottom); |
#endif |
break; |
|
case SS_BITMAP: |
#if 0 /* jmt: fix: no FillBoxWithBitmap() */ |
FillBoxWithBitmap(hdc, 0, 0, 0, 0, |
(PBITMAP)(pCtrl->userdata)); |
#endif |
break; |
|
case SS_ICON: |
#if 0 /* jmt: fix: no DrawIcon */ |
hIcon = (HICON)(pCtrl->userdata); |
DrawIcon (hdc, 0, 0, 0, 0, hIcon); |
#endif |
break; |
|
case SS_SIMPLE: |
#if 0 |
SetBrushColor (hdc, GetWindowBkColor (hwnd)); |
FillBox (hdc, 0, 0, rcClient.right, rcClient.bottom); |
#else |
hbr=CreateSolidBrush(GetWindowBkColor(hwnd)); |
rc.left=0; rc.top=0; rc.bottom=rcClient.bottom; rc.right=rcClient.right; |
FillRect(hdc,&rc,hbr); |
DeleteObject(hbr); |
#endif |
if (dwStyle & WS_DISABLED) |
SetTextColor (hdc, DKGRAY); |
else |
SetTextColor (hdc, BLACK); |
SetBkColor(hdc, GetSysColor(COLOR_BTNFACE)); |
spCaption = GetWindowCaption (hwnd); |
if (spCaption) |
{ |
SelectObject(hdc, GetStockObject(FONT_NAME)); |
TextOut (hdc, 0, 0, spCaption, -1); |
} |
break; |
|
case SS_LEFT: |
case SS_CENTER: |
case SS_RIGHT: |
case SS_LEFTNOWORDWRAP: |
uFormat = DT_TOP; |
if ( (dwStyle & SS_TYPEMASK) == SS_LEFT) |
uFormat |= DT_LEFT | DT_WORDBREAK; |
else if ( (dwStyle & SS_TYPEMASK) == SS_CENTER) |
uFormat |= DT_CENTER | DT_WORDBREAK; |
else if ( (dwStyle & SS_TYPEMASK) == SS_RIGHT) |
uFormat |= DT_RIGHT | DT_WORDBREAK; |
else if ( (dwStyle & SS_TYPEMASK) == SS_LEFTNOWORDWRAP) |
uFormat |= DT_LEFT | DT_SINGLELINE | DT_EXPANDTABS; |
|
if (dwStyle & WS_DISABLED) |
SetTextColor (hdc, DKGRAY); |
else |
SetTextColor (hdc, BLACK); |
|
#if 0 |
SetBkColor (hdc, GetWindowBkColor (hwnd)); |
#endif |
SetBkColor(hdc, GetSysColor(COLOR_BTNFACE)); |
spCaption = GetWindowCaption (hwnd); |
if (dwStyle & SS_NOPREFIX) |
uFormat |= DT_NOPREFIX; |
|
if (spCaption) |
{ |
SelectObject(hdc, GetStockObject(FONT_NAME)); |
DrawText (hdc, spCaption, -1, &rcClient, uFormat); |
} |
break; |
|
case SS_GROUPBOX: |
#if 0 |
Draw3DBorder (hdc, rcClient.left, |
rcClient.top + (GetSysCharHeight(hwnd) >> 1), |
rcClient.right, rcClient.bottom); |
#else |
Draw3dInset(hdc, rcClient.left, |
rcClient.top+(GetSysCharHeight(hwnd) >> 1), |
rcClient.right-rcClient.left, |
rcClient.bottom-rcClient.top); |
#endif |
if (dwStyle & WS_DISABLED) |
SetTextColor (hdc, DKGRAY); |
else |
SetTextColor (hdc, BLACK); |
|
#if 0 |
SetBkColor(hdc, GetWindowBkColor (GetParent (hwnd))); |
#endif |
SetBkColor(hdc, GetSysColor(COLOR_BTNFACE)); |
spCaption = GetWindowCaption (hwnd); |
if (spCaption) |
{ |
SelectObject(hdc, GetStockObject(FONT_NAME)); |
TextOut (hdc, GetSysCharWidth (hwnd), 2, spCaption, -1); |
} |
break; |
} |
EndPaint (hwnd, &ps); |
} |
break; |
|
#if 0 /* jmt: SS_NOTIFY isn't standard in win32 */ |
case WM_LBUTTONDBLCLK: |
if (GetWindowStyle (hwnd) & SS_NOTIFY) |
SendMessage (GetParent(hwnd), WM_COMMAND, |
(WPARAM)MAKELONG(pCtrl->id, STN_DBLCLK), |
(LPARAM)hwnd); |
break; |
#endif |
case WM_LBUTTONDOWN: |
break; |
|
case WM_NCLBUTTONDBLCLK: |
break; |
|
case WM_NCLBUTTONDOWN: |
break; |
|
case WM_NCHITTEST: |
dwStyle = GetWindowStyle (hwnd); |
if ((dwStyle & SS_TYPEMASK) == SS_GROUPBOX) |
return HTTRANSPARENT; |
|
#if 0 /* jmt: SS_NOTIFY isn't standard in win32 */ |
if (GetWindowStyle (hwnd) & SS_NOTIFY) |
return HTCLIENT; |
else |
#endif |
return HTNOWHERE; |
break; |
|
|
#if 0 /* jmt: fix: no WM_GETFONT/WM_SETFONT */ |
case WM_GETFONT: |
break; |
case WM_SETFONT: |
break; |
#endif |
case WM_SETTEXT: |
SetWindowCaption (hwnd, (char*)lParam); |
InvalidateRect (hwnd, NULL, TRUE); |
break; |
|
default: |
return DefWindowProc (hwnd, message, wParam, lParam); |
} |
return 0; |
} |
/scrlbar.c
0,0 → 1,1140
/* |
* Copyright (c) 2000 Greg Haerr <greg@censoft.com> |
* Portions Copyright (c) 1999, 2000, Wei Yongming. |
* jmt: scrollbar thumb ported |
* |
* Microwindows win32 Scrollbars control |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#define MWINCLUDECOLORS /* jmt: for color macros */ |
#include "windows.h" |
#include "wintern.h" |
#include "wintools.h" |
|
/* scrollbar status/positions*/ |
#define SBS_UNKNOWN 0x0000 |
#define SBS_LEFTARROW 0x0001 |
#define SBS_RIGHTARROW 0x0002 |
#define SBS_LEFTSPACE 0x0004 |
#define SBS_RIGHTSPACE 0x0008 |
#define SBS_HORZTHUMB 0x0010 |
#define SBS_UPARROW 0x0020 |
#define SBS_DOWNARROW 0x0040 |
#define SBS_UPSPACE 0x0080 |
#define SBS_DOWNSPACE 0x0100 |
#define SBS_VERTTHUMB 0x0200 |
#define SBS_MASK 0x03ff |
#define SBS_DISABLED 0x4000 |
#define SBS_HIDE 0x8000 |
|
|
#define MWM_DEFBARLEN 18 |
#define MWM_MINBARLEN 8 |
|
static LRESULT CALLBACK |
ScrollbarControlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); |
|
|
int WINAPI MwRegisterScrollbarControl(HINSTANCE hInstance) |
{ |
WNDCLASS wc; |
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; |
wc.lpfnWndProc = (WNDPROC)ScrollbarControlProc; |
wc.cbClsExtra = 0; |
wc.cbWndExtra = 0; |
wc.hInstance = hInstance; |
wc.hIcon = NULL; |
wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/ |
wc.hbrBackground= GetStockObject(WHITE_BRUSH); |
wc.lpszMenuName = NULL; |
wc.lpszClassName= "SCROLLBAR"; |
|
return RegisterClass(&wc); |
} |
|
static DWORD GetWindowStyle (HWND hwnd) |
{ |
return hwnd->style; |
} |
|
static int |
wndGetBorder(HWND hwnd) |
{ |
if (hwnd->style & WS_BORDER) { |
if ((hwnd->style & WS_CAPTION) == WS_CAPTION) |
return mwSYSMETRICS_CXFRAME; |
return mwSYSMETRICS_CXBORDER; |
} |
return 0; |
} |
|
static BOOL |
wndGetVScrollBarRect (HWND hwnd, RECT* rcVBar) |
{ |
int cx,cy; RECT rc; |
MWSCROLLBARINFO* pData; |
|
pData = (MWSCROLLBARINFO *)hwnd->userdata; |
rc = hwnd->winrect; |
cx=rc.right-rc.left; |
cy=rc.bottom-rc.top; |
|
rcVBar->left = hwnd->winrect.right - cx |
- wndGetBorder (hwnd); |
rcVBar->right = hwnd->winrect.right - wndGetBorder (hwnd); |
rcVBar->top = hwnd->winrect.top; |
rcVBar->bottom = hwnd->winrect.bottom - wndGetBorder (hwnd); |
|
return TRUE; |
} |
|
static BOOL |
wndGetHScrollBarRect (HWND hwnd, RECT* rcHBar) |
{ |
int cx,cy; RECT rc; |
MWSCROLLBARINFO* pData; |
|
pData = (MWSCROLLBARINFO *)hwnd->userdata; |
rc = hwnd->winrect; |
cx=rc.right-rc.left; |
cy=rc.bottom-rc.top; |
|
rcHBar->top = hwnd->winrect.bottom - cy |
- wndGetBorder (hwnd); |
rcHBar->bottom = hwnd->winrect.bottom - wndGetBorder (hwnd); |
rcHBar->left = hwnd->winrect.left; |
rcHBar->right = hwnd->winrect.right - wndGetBorder (hwnd); |
|
return TRUE; |
} |
|
void |
MwPaintScrollbars(HWND hwnd, HDC hdc, DWORD style) |
{ |
BOOL vertbar = (style==SBS_VERT); |
BOOL horzbar = (style==SBS_HORZ); |
BOOL fGotDC = FALSE; |
RECT rc,rc2; |
|
POINT p3[3]; |
int shrink=2; |
|
int start = 0; |
RECT rcHBar, rcVBar; |
|
int cx,cy; |
MWSCROLLBARINFO* pData; |
|
pData = (MWSCROLLBARINFO *)hwnd->userdata; |
rc = hwnd->winrect; |
cx=rc.right-rc.left; |
cy=rc.bottom-rc.top; |
|
if (!hdc && (horzbar || vertbar)) { |
hdc = GetWindowDC(hwnd); |
fGotDC = TRUE; |
} |
|
if (vertbar) { |
|
#if 1 |
/* bkgnd */ |
rc2.left=rc.left; rc2.right=rc2.left+ cx; |
rc2.top=rc.top; |
rc2.bottom=rc2.top+ cx; |
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1)); |
rc2.top=rc.bottom- cx; |
rc2.bottom=rc2.top+ cx; |
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1)); |
#endif |
/* up */ |
Draw3dUpDownState(hdc, rc.left, rc.top, |
cx, cx, |
pData->status & SBS_UPARROW); |
/* down */ |
Draw3dUpDownState(hdc, rc.left,rc.bottom-cx, |
cx, cx, |
pData->status & SBS_DOWNARROW); |
/* jmt: draw arrows */ |
SelectObject(hdc,GetStockObject(BLACK_BRUSH)); |
/* up */ |
p3[0].x= rc.left + (cx/2) - 1; |
p3[0].y= rc.top + 2 + shrink; |
p3[1].x= rc.left + 2 + shrink - 1; |
p3[1].y= rc.top + (cx-4) - shrink; |
p3[2].x= rc.left + (cx-4) - shrink; |
p3[2].y= rc.top + (cx-4) - shrink; |
Polygon(hdc,p3,3); |
/* down */ |
p3[0].x= rc.left + (cx/2) - 1; |
p3[0].y= rc.bottom - 4 - shrink; |
p3[1].x= rc.left + 2 + shrink - 1; |
p3[1].y= rc.bottom-cx + 2 + shrink; |
p3[2].x= rc.left + (cx-4) - shrink; |
p3[2].y= rc.bottom-cx + 2 + shrink; |
Polygon(hdc,p3,3); |
|
/* draw moving bar */ |
|
wndGetVScrollBarRect (hwnd, &rcVBar); |
rcVBar.left -- ; |
/*rcVBar.right -- ;*/ |
|
start = rcVBar.top + cx + pData->barStart; |
|
if (start + pData->barLen > rcVBar.bottom) |
start = rcVBar.bottom - pData->barLen; |
|
if (pData->barLen == 0) |
pData->barLen=rc.bottom-rc.top-(cx*2); |
|
/* bkgnd */ |
rc2.left=rc.left; rc2.right=rc.right/*-1*/; |
rc2.top=rc.top+cx; |
rc2.bottom=start; |
if (rc2.bottom>rc2.top) |
FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); |
|
rc2.top=start+pData->barLen; |
rc2.bottom=rc.bottom-cx; |
if (rc2.bottom>rc2.top) |
FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); |
|
Draw3dUpFrame (hdc, rcVBar.left, start, rcVBar.right, |
start + pData->barLen); |
/*printf("barv:(l,t,r,b):(%d,%d,%d,%d)\n", |
rcVBar.left, start, rcVBar.right, |
start + pData->barLen);*/ |
|
} |
if (horzbar) { |
#if 1 |
/* bkgnd */ |
rc2.top=rc.top; rc2.bottom=rc2.top+ cy; |
rc2.left=rc.left; |
rc2.right=rc2.left+ cy; |
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1)); |
rc2.left=rc.right- cy; |
rc2.right=rc2.left+ cy; |
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1)); |
#endif |
/* left */ |
Draw3dUpDownState(hdc, rc.left, rc.top, |
cy, cy, |
pData->status & SBS_LEFTARROW); |
/* right */ |
Draw3dUpDownState(hdc, rc.right-cy, rc.top, |
cy, cy, |
pData->status & SBS_RIGHTARROW); |
/* jmt: draw arrows */ |
SelectObject(hdc,GetStockObject(BLACK_BRUSH)); |
/* left */ |
p3[0].x= rc.left + 2 + shrink; |
p3[0].y= rc.top + (cy/2) ; |
p3[1].x= rc.left + (cy-4) - shrink ; |
p3[1].y= rc.top + 2 + shrink; |
p3[2].x= rc.left + (cy-4) - shrink; |
p3[2].y= rc.bottom - 4 - shrink + 1; |
Polygon(hdc,p3,3); |
/* right */ |
p3[0].x= rc.right - 4 - shrink; |
p3[0].y= rc.top + (cy/2) ; |
p3[1].x= rc.right-cy + 2 + shrink ; |
p3[1].y= rc.top + 2 + shrink; |
p3[2].x= rc.right-cy + 2 + shrink; |
p3[2].y= rc.bottom - 4 - shrink + 1; |
Polygon(hdc,p3,3); |
|
/* draw moving bar. */ |
|
wndGetHScrollBarRect (hwnd, &rcHBar); |
rcHBar.top -- ; |
/*rcHBar.bottom -- ;*/ |
|
start = rcHBar.left + cy + pData->barStart; |
|
if (start + pData->barLen > rcHBar.right) |
start = rcHBar.right - pData->barLen; |
|
if (pData->barLen == 0) |
pData->barLen=rc.right-rc.left-(cy*2); |
|
/* bkgnd */ |
rc2.top=rc.top; rc2.bottom=rc.bottom/*-1*/; |
rc2.left=rc.left+cy; |
rc2.right=start; |
if (rc2.right>rc2.left) |
FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); |
|
rc2.left=start+pData->barLen; |
rc2.right=rc.right-cy; |
if (rc2.right>rc2.left) |
FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); |
|
Draw3dUpFrame (hdc, start, rcHBar.top, start + pData->barLen, |
rcHBar.bottom); |
/*printf("barh:(l,t,r,b):(%d,%d,%d,%d)\n", |
start, rcHBar.top, start + pData->barLen, |
rcHBar.bottom);*/ |
} |
|
if (fGotDC) |
ReleaseDC(hwnd, hdc); |
} |
|
/* handle a non-client message for a scrollbar*/ |
void |
MwHandleMessageScrollbar(HWND hwnd, WPARAM hitcode, LPARAM lParam, UINT msg, DWORD style) |
{ |
int pos = SBS_UNKNOWN; |
BOOL vertbar = (style==SBS_VERT); |
BOOL horzbar = (style==SBS_HORZ); |
int * pStat; |
POINT pt; |
RECT rc; |
|
static BOOL bDraw; |
|
static int downPos = SBS_UNKNOWN; |
static int sbCode; |
int newThumbPos; |
|
int itemMoveable,itemCount,itemVisible,moveRange; /* jmt:2k0819 */ |
int moveTop,moveBottom,moveLeft,moveRight; /* jmt:2k0819 */ |
|
int cx,cy; |
MWSCROLLBARINFO* pData; |
|
pData = (MWSCROLLBARINFO *)hwnd->userdata; |
rc = hwnd->winrect; |
cx=rc.right-rc.left; |
cy=rc.bottom-rc.top; |
|
POINTSTOPOINT(pt, lParam); |
for (;;) { /* use for() to allow break statement*/ |
if (vertbar) |
{ |
pStat = &pData->status; |
rc = hwnd->winrect; |
rc.bottom = rc.top + cx; |
if (PtInRect(&rc, pt)) |
{ |
pos = SBS_UPARROW; |
break; |
} |
rc.bottom = hwnd->winrect.bottom; |
rc.top = rc.bottom - cx; |
if (PtInRect(&rc, pt)) |
{ |
pos = SBS_DOWNARROW; |
break; |
} |
pos = SBS_VERTTHUMB; |
} else if (horzbar) |
{ |
pStat = &pData->status; |
rc = hwnd->winrect; |
rc.right = rc.left + cy; |
if (PtInRect(&rc, pt)) { |
pos = SBS_LEFTARROW; |
break; |
} |
rc.right = hwnd->winrect.right; |
rc.left = rc.right - cy; |
if (PtInRect(&rc, pt)) { |
pos = SBS_RIGHTARROW; |
break; |
} |
pos = SBS_HORZTHUMB; |
} else |
return; |
break; |
} |
|
if (pos == SBS_UNKNOWN) |
return; |
|
*pStat &= ~SBS_MASK; /* remove stray mouse states*/ |
|
if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK) |
*pStat |= pos; |
else *pStat &= ~pos; |
|
if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK) |
bDraw=TRUE; |
|
if (bDraw) |
MwPaintScrollbars(hwnd, NULL,style); |
|
if (pos == SBS_UPARROW || pos == SBS_LEFTARROW) /* jmt:2k0820 */ |
{ |
if (pData->curPos != pData->minPos) |
sbCode = SB_LINEUP; |
} |
else if (pos == SBS_DOWNARROW || pos == SBS_RIGHTARROW) /* jmt:2k0820 */ |
{ |
if (pData->curPos != pData->maxPos) |
sbCode = SB_LINEDOWN; |
} |
else if (pos == SBS_VERTTHUMB || pos == SBS_HORZTHUMB) |
{ |
sbCode = SB_THUMBTRACK; |
} |
|
switch(msg) |
{ |
case WM_NCLBUTTONDOWN: |
case WM_NCLBUTTONDBLCLK: |
downPos = pos; |
break; |
|
case WM_NCMOUSEMOVE: |
if (vertbar) |
{ |
if (sbCode == SB_THUMBTRACK && downPos == SBS_VERTTHUMB) |
{ |
/* jmt(2k0819): new algorithm for SB_THUMBTRACK */ |
|
rc = hwnd->winrect; |
moveTop = rc.top + cx; |
moveBottom = hwnd->winrect.bottom - cx; |
moveRange = moveBottom - moveTop; |
|
itemCount = pData->maxPos - pData->minPos + 1; |
itemVisible = pData->pageStep; |
itemMoveable = itemCount - itemVisible + 1; |
|
newThumbPos = ((pt.y - moveTop) * itemMoveable) / moveRange; |
printf("((%d-%d)*%d)/%d=%d\n", |
pt.y,moveTop,itemMoveable,moveRange,newThumbPos); |
|
if ( newThumbPos >= pData->minPos && |
newThumbPos <= pData->maxPos) |
{ |
SendMessage (hwnd, |
WM_VSCROLL, SB_THUMBTRACK, newThumbPos); |
|
SendMessage (GetParent(hwnd), |
WM_VSCROLL, SB_THUMBTRACK, newThumbPos); |
} |
break; |
} |
} |
if (horzbar) |
{ |
if (sbCode == SB_THUMBTRACK && downPos == SBS_HORZTHUMB) |
{ |
/* jmt(2k0819): new algorithm for SB_THUMBTRACK */ |
|
rc = hwnd->winrect; |
moveLeft = rc.left + cy; |
moveRight = hwnd->winrect.right - cy; |
moveRange = moveRight - moveLeft; |
|
itemCount = pData->maxPos - pData->minPos + 1; |
itemVisible = pData->pageStep; |
itemMoveable = itemCount - itemVisible + 1; |
|
newThumbPos = ((pt.x - moveLeft) * itemMoveable) / moveRange; |
printf("((%d-%d)*%d)/%d=%d\n", |
pt.y,moveLeft,itemMoveable,moveRange,newThumbPos); |
|
if ( newThumbPos >= pData->minPos && |
newThumbPos <= pData->maxPos) |
{ |
SendMessage (hwnd, |
WM_HSCROLL, SB_THUMBTRACK, newThumbPos); |
|
SendMessage (GetParent(hwnd), |
WM_HSCROLL, SB_THUMBTRACK, newThumbPos); |
} |
break; |
} |
} |
break; |
|
case WM_NCLBUTTONUP: |
bDraw=FALSE; |
downPos = SBS_UNKNOWN; |
|
if (sbCode==SB_THUMBTRACK) |
{ |
if (vertbar) |
{ |
/* jmt(2k0819): new algorithm for SB_THUMBTRACK */ |
|
rc = hwnd->winrect; |
moveTop = rc.top + cx; |
moveBottom = hwnd->winrect.bottom - cx; |
moveRange = moveBottom - moveTop; |
|
itemCount = pData->maxPos - pData->minPos + 1; |
itemVisible = pData->pageStep; |
itemMoveable = itemCount - itemVisible + 1; |
|
newThumbPos = ((pt.y - moveTop) * itemMoveable) / moveRange; |
printf("((%d-%d)*%d)/%d=%d\n", |
pt.y,moveTop,itemMoveable,moveRange,newThumbPos); |
|
if ( newThumbPos >= pData->minPos && |
newThumbPos <= pData->maxPos) |
{ |
SendMessage (hwnd, |
WM_VSCROLL, SB_THUMBTRACK, newThumbPos); |
|
SendMessage (GetParent(hwnd), |
WM_VSCROLL, SB_THUMBTRACK, newThumbPos); |
} |
break; /* case */ |
} |
if (horzbar) |
{ |
/* jmt(2k0819): new algorithm for SB_THUMBTRACK */ |
|
rc = hwnd->winrect; |
moveLeft = rc.left + cy; |
moveRight = hwnd->winrect.right - cy; |
moveRange = moveRight - moveLeft; |
|
itemCount = pData->maxPos - pData->minPos + 1; |
itemVisible = pData->pageStep; |
itemMoveable = itemCount - itemVisible + 1; |
|
newThumbPos = ((pt.x - moveLeft) * itemMoveable) / moveRange; |
printf("((%d-%d)*%d)/%d=%d\n", |
pt.y,moveLeft,itemMoveable,moveRange,newThumbPos); |
|
if ( newThumbPos >= pData->minPos && |
newThumbPos <= pData->maxPos) |
{ |
SendMessage (hwnd, |
WM_HSCROLL, SB_THUMBTRACK, newThumbPos); |
|
SendMessage (GetParent(hwnd), |
WM_HSCROLL, SB_THUMBTRACK, newThumbPos); |
} |
break; /* case */ |
} |
} |
else |
{ |
if (vertbar) |
{ |
SendMessage (hwnd, WM_VSCROLL, sbCode, 0); |
SendMessage (GetParent(hwnd), WM_VSCROLL, sbCode, 0); |
} |
if (horzbar) |
{ |
SendMessage (hwnd, WM_HSCROLL, sbCode, 0); |
SendMessage (GetParent(hwnd), WM_HSCROLL, sbCode, 0); |
} |
} |
break; |
} |
} |
|
|
static BOOL |
PtInRect2(const RECT *lprc, int x, int y) |
{ |
POINT p; |
|
p.x = x; |
p.y = y; |
return PtInRect(lprc, p); |
} |
|
static void |
wndScrollBarPos (HWND hwnd, BOOL bIsHBar, RECT* rcBar) /* jmt: 2k0820 */ |
{ |
UINT moveRange; |
PMWSCROLLBARINFO pSBar; |
int cx,cy; |
RECT rc; |
|
rc = hwnd->winrect; |
cx=rc.right-rc.left; |
cy=rc.bottom-rc.top; |
pSBar = (MWSCROLLBARINFO *)hwnd->userdata; |
|
if (pSBar->minPos == pSBar->maxPos) { |
pSBar->status |= SBS_HIDE; |
return; |
} |
|
if (bIsHBar) |
moveRange = (rcBar->right - rcBar->left) - (cy << 1); |
else |
moveRange = (rcBar->bottom - rcBar->top) - (cx << 1); |
|
|
if (pSBar->pageStep == 0) |
{ |
pSBar->barLen = MWM_DEFBARLEN; |
|
if (pSBar->barLen > moveRange) |
pSBar->barLen = MWM_MINBARLEN; |
} |
else |
{ |
pSBar->barLen = moveRange * pSBar->pageStep / |
(pSBar->maxPos - pSBar->minPos + 1); |
if (pSBar->barLen < MWM_MINBARLEN) |
pSBar->barLen = MWM_MINBARLEN; |
} |
|
pSBar->barStart = moveRange * (pSBar->curPos - pSBar->minPos) / |
(pSBar->maxPos - pSBar->minPos + 1); |
|
|
if (pSBar->barStart + pSBar->barLen > moveRange) |
pSBar->barStart = moveRange - pSBar->barLen; |
|
|
if (pSBar->barStart < 0) |
pSBar->barStart = 0; |
} |
|
static PMWSCROLLBARINFO wndGetScrollBar (HWND pWin) /* jmt: 2k0820 */ |
{ |
MWSCROLLBARINFO* pData; |
|
pData = (MWSCROLLBARINFO *)pWin->userdata; |
|
if (!strcmp(pWin->pClass->lpszClassName,"SCROLLBAR")) |
return pData; |
else |
return NULL; |
} |
|
BOOL EnableScrollBarEx (HWND hWnd, int iSBar, BOOL bEnable) /* jmt: iSBar not used */ |
{ |
PMWSCROLLBARINFO pSBar; |
HWND pWin; |
BOOL bPrevState; |
RECT rcBar; |
|
DWORD dwStyle; /* jmt:2k0820 */ |
|
pWin = (HWND)hWnd; |
|
if ( !(pSBar = wndGetScrollBar (pWin)) ) |
return FALSE; |
|
bPrevState = !(pSBar->status & SBS_DISABLED); |
|
if (bEnable && !bPrevState) |
pSBar->status &= ~SBS_DISABLED; |
else if (!bEnable && bPrevState) |
pSBar->status |= SBS_DISABLED; |
else |
return FALSE; |
|
dwStyle = (GetWindowStyle (hWnd) & SBS_TYPEMASK); /* jmt: 2k0820 */ |
|
if (dwStyle == SBS_VERT) |
{ |
wndGetVScrollBarRect (pWin, &rcBar); |
rcBar.left --; |
rcBar.right --; |
} |
else |
{ |
wndGetHScrollBarRect (pWin, &rcBar); |
rcBar.top --; |
rcBar.bottom --; |
} |
#if 0 |
SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar)); |
#else |
MwPaintScrollbars(hWnd,NULL,dwStyle); /* a must */ |
#endif |
|
return TRUE; |
} |
|
BOOL GetScrollPosEx (HWND hWnd, int iSBar, int* pPos) /* jmt: iSBar not used */ |
{ |
PMWSCROLLBARINFO pSBar; |
HWND pWin; |
|
pWin = (HWND)hWnd; |
|
if ( !(pSBar = wndGetScrollBar (pWin)) ) |
return FALSE; |
|
*pPos = pSBar->curPos; |
return TRUE; |
} |
|
BOOL GetScrollRangeEx (HWND hWnd, int iSBar, int* pMinPos, int* pMaxPos) /* jmt: iSBar not used */ |
{ |
PMWSCROLLBARINFO pSBar; |
HWND pWin; |
|
pWin = (HWND)hWnd; |
|
if ( !(pSBar = wndGetScrollBar (pWin)) ) |
return FALSE; |
|
*pMinPos = pSBar->minPos; |
*pMaxPos = pSBar->maxPos; |
return TRUE; |
} |
|
BOOL SetScrollPosEx (HWND hWnd, int iSBar, int iNewPos) /* jmt: iSBar not used */ |
{ |
PMWSCROLLBARINFO pSBar; |
HWND pWin; |
RECT rcBar; |
|
DWORD dwStyle; /* jmt:2k0820 */ |
|
pWin = (HWND)hWnd; |
|
if ( !(pSBar = wndGetScrollBar (pWin)) ) |
return FALSE; |
|
if (iNewPos < pSBar->minPos) |
pSBar->curPos = pSBar->minPos; |
else |
pSBar->curPos = iNewPos; |
|
{ |
int max = pSBar->maxPos; |
max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0; |
|
if (pSBar->curPos > max) |
pSBar->curPos = max; |
} |
|
dwStyle = (GetWindowStyle (hWnd) & SBS_TYPEMASK); /* jmt: 2k0820 */ |
|
if (dwStyle == SBS_VERT) |
{ |
wndGetVScrollBarRect (pWin, &rcBar); |
rcBar.left --; |
rcBar.right --; |
} |
else |
{ |
wndGetHScrollBarRect (pWin, &rcBar); |
rcBar.top --; |
rcBar.bottom --; |
} |
|
wndScrollBarPos (pWin, dwStyle == SBS_HORZ, &rcBar); |
|
#if 0 |
SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar)); |
#else |
MwPaintScrollbars(hWnd,NULL,dwStyle); /* a must */ |
#endif |
return TRUE; |
} |
|
BOOL SetScrollRangeEx (HWND hWnd, int iSBar, int iMinPos, int iMaxPos) /* jmt: iSBar not used */ |
{ |
PMWSCROLLBARINFO pSBar; |
HWND pWin; |
RECT rcBar; |
|
DWORD dwStyle; /* jmt:2k0820 */ |
|
pWin = (HWND)hWnd; |
|
if ( !(pSBar = wndGetScrollBar (pWin)) ) |
return FALSE; |
|
pSBar->minPos = (iMinPos < iMaxPos)?iMinPos:iMaxPos; |
pSBar->maxPos = (iMinPos > iMaxPos)?iMinPos:iMaxPos; |
|
/* validate parameters. */ |
if (pSBar->curPos < pSBar->minPos) |
pSBar->curPos = pSBar->minPos; |
|
if (pSBar->pageStep <= 0) |
pSBar->pageStep = 0; |
else if (pSBar->pageStep > (pSBar->maxPos - pSBar->minPos + 1)) |
pSBar->pageStep = pSBar->maxPos - pSBar->minPos + 1; |
|
{ |
int max = pSBar->maxPos; |
max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0; |
|
if (pSBar->curPos > max) |
pSBar->curPos = max; |
} |
|
dwStyle = (GetWindowStyle (hWnd) & SBS_TYPEMASK); /* jmt: 2k0820 */ |
|
if (dwStyle == SBS_VERT) |
{ |
wndGetVScrollBarRect (pWin, &rcBar); |
rcBar.left --; |
rcBar.right --; |
} |
else |
{ |
wndGetHScrollBarRect (pWin, &rcBar); |
rcBar.top --; |
rcBar.bottom --; |
} |
wndScrollBarPos (pWin, dwStyle == SBS_HORZ, &rcBar); |
|
#if 0 |
SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar)); |
#else |
MwPaintScrollbars(hWnd,NULL,dwStyle); /* a must */ |
#endif |
|
return TRUE; |
} |
|
BOOL SetScrollInfoEx (HWND hWnd, int iSBar, |
LPCSCROLLINFO lpsi, BOOL fRedraw) /* jmt: iSBar not used */ |
{ |
PMWSCROLLBARINFO pSBar; |
HWND pWin; |
RECT rcBar; |
|
DWORD dwStyle; /* jmt:2k0820 */ |
|
pWin = (HWND)hWnd; |
|
if ( !(pSBar = wndGetScrollBar (pWin)) ) |
return FALSE; |
|
if( lpsi->fMask & SIF_RANGE ) |
{ |
pSBar->minPos = (lpsi->nMin < lpsi->nMax)?lpsi->nMin:lpsi->nMax; |
pSBar->maxPos = (lpsi->nMin < lpsi->nMax)?lpsi->nMax:lpsi->nMin; |
} |
|
if( lpsi->fMask & SIF_POS ) |
pSBar->curPos = lpsi->nPos; |
|
if( lpsi->fMask & SIF_PAGE ) |
pSBar->pageStep = lpsi->nPage; |
|
/* validate parameters. */ |
if (pSBar->curPos < pSBar->minPos) |
pSBar->curPos = pSBar->minPos; |
|
if (pSBar->pageStep <= 0) |
pSBar->pageStep = 0; |
else if (pSBar->pageStep > (pSBar->maxPos - pSBar->minPos + 1)) |
pSBar->pageStep = pSBar->maxPos - pSBar->minPos + 1; |
|
{ |
int max = pSBar->maxPos; |
max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0; |
|
if (pSBar->curPos > max) |
pSBar->curPos = max; |
} |
|
dwStyle = (GetWindowStyle (hWnd) & SBS_TYPEMASK); /* jmt: 2k0820 */ |
|
if(fRedraw) |
{ |
if (dwStyle == SBS_VERT) |
{ |
wndGetVScrollBarRect (pWin, &rcBar); |
rcBar.left --; |
rcBar.right --; |
} |
else |
{ |
wndGetHScrollBarRect (pWin, &rcBar); |
rcBar.top --; |
rcBar.bottom --; |
} |
wndScrollBarPos (pWin, dwStyle == SBS_HORZ, &rcBar); |
|
#if 0 |
SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar)); |
#else |
MwPaintScrollbars(hWnd,NULL,dwStyle); /* a must */ |
#endif |
} |
|
return TRUE; |
} |
|
BOOL GetScrollInfoEx(HWND hWnd, int iSBar, LPSCROLLINFO lpsi) /* jmt: iSBar not used */ |
{ |
PMWSCROLLBARINFO pSBar; |
HWND pWin; |
|
pWin = (HWND)hWnd; |
|
if ( !(pSBar = wndGetScrollBar (pWin)) ) |
return FALSE; |
|
if( lpsi->fMask & SIF_RANGE ) |
{ |
lpsi->nMin = pSBar->minPos; |
lpsi->nMax = pSBar->maxPos; |
} |
|
if( lpsi->fMask & SIF_POS ) |
{ |
lpsi->nPos = pSBar->curPos; |
} |
|
if( lpsi->fMask & SIF_PAGE ) |
lpsi->nPage = pSBar->pageStep; |
|
return TRUE; |
} |
|
BOOL ShowScrollBarEx (HWND hWnd, int iSBar, BOOL bShow) /* jmt: iSBar not used */ |
{ |
PMWSCROLLBARINFO pSBar; |
HWND pWin; |
BOOL bPrevState; |
RECT rcBar; |
|
DWORD dwStyle; /* jmt:2k0820 */ |
|
pWin = (HWND)hWnd; |
|
if ( !(pSBar = wndGetScrollBar (pWin)) ) |
return FALSE; |
|
bPrevState = !(pSBar->status & SBS_HIDE); |
|
if (bShow && !bPrevState) |
pSBar->status &= ~SBS_HIDE; |
else if (!bShow && bPrevState) |
pSBar->status |= SBS_HIDE; |
else |
return FALSE; |
|
#if 0 /* fix: no WM_CHANGESIZE */ |
SendMessage (hWnd, WM_CHANGESIZE, 0, 0); |
#endif |
|
dwStyle = (GetWindowStyle (hWnd) & SBS_TYPEMASK); /* jmt: 2k0820 */ |
|
if (dwStyle == SBS_VERT) |
wndGetVScrollBarRect (pWin, &rcBar); |
else |
wndGetHScrollBarRect (pWin, &rcBar); |
|
{ |
RECT rcWin, rcClient; |
|
memcpy (&rcWin, &pWin->winrect.left, sizeof (RECT)); |
|
rcClient.left = 0; |
rcClient.top = 0; |
rcClient.right = pWin->clirect.right - pWin->clirect.left; |
rcClient.bottom = pWin->clirect.bottom - pWin->clirect.top; |
#if 0 /* fix: no WM_SIZECHANGED */ |
SendMessage (hWnd, WM_SIZECHANGED, |
(WPARAM)&rcWin, (LPARAM)&rcClient); |
#endif |
} |
|
if (bShow) { |
SendMessage (hWnd, WM_NCPAINT, 0, 0); |
} |
else { |
rcBar.left -= pWin->clirect.left; |
rcBar.top -= pWin->clirect.top; |
rcBar.right -= pWin->clirect.left; |
rcBar.bottom -= pWin->clirect.top; |
SendMessage (hWnd, WM_NCPAINT, 0, 0); |
InvalidateRect (hWnd, &rcBar, TRUE); |
} |
|
return TRUE; |
} |
|
static void sbSetScrollInfo (HWND hwnd, PMWSCROLLBARINFO pData, BOOL fRedraw) /* jmt:2k0820 */ |
{ |
SCROLLINFO si; |
|
int itemCount,itemVisibles; |
|
itemCount = pData->maxPos - pData->minPos + 1; |
itemVisibles = pData->pageStep; |
|
if (itemVisibles >= itemCount) |
{ |
SetScrollPosEx (hwnd, 0, 0); /* jmt: arg2 not used */ |
EnableScrollBarEx (hwnd, 0, FALSE); /* jmt: arg2 not used */ |
return; |
} |
|
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; |
si.nMax = itemCount - 1; |
si.nMin = 0; |
|
si.nPage = itemVisibles; /* jmt(2k0819): new algorithm for SB_THUMBTRACK */ |
|
si.nPos = pData->curPos; |
|
SetScrollInfoEx (hwnd, 0, &si, fRedraw); /* jmt: arg2 not used */ |
EnableScrollBarEx (hwnd, 0, TRUE); /* jmt: arg2 not used */ |
} |
|
static LRESULT CALLBACK |
ScrollbarControlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* jmt:2k0820 */ |
{ |
DWORD dwStyle; |
MWSCROLLBARINFO* pData; |
|
int moveRange; |
RECT rcBar; |
|
dwStyle = (GetWindowStyle (hwnd) & SBS_TYPEMASK); |
switch (message) |
{ |
case WM_CREATE: |
if (!(pData = malloc (sizeof (MWSCROLLBARINFO)))) |
{ |
fprintf(stderr, "Create scroll bar control failure!\n"); |
return -1; |
} |
|
pData->minPos=0; /* min value of scroll range.*/ |
/* max value of scroll range.*/ |
pData->maxPos=0; |
if (dwStyle==SBS_VERT) |
moveRange=((hwnd->winrect.bottom-hwnd->winrect.top) |
-((hwnd->winrect.right-hwnd->winrect.left)<<1)); |
else |
moveRange=((hwnd->winrect.right-hwnd->winrect.left) |
-((hwnd->winrect.bottom-hwnd->winrect.top)<<1)); |
if (moveRange > MWM_MINBARLEN) |
{ |
|
|
pData->maxPos=moveRange / MWM_MINBARLEN; |
if( (moveRange % MWM_MINBARLEN) ) |
pData->maxPos++; |
} |
printf("maxPos=%d\n",pData->maxPos); |
|
pData->curPos=0; /* current scroll pos.*/ |
|
/* steps per page.*/ |
pData->pageStep=1; |
if ( (pData->maxPos - 2) > 1) |
pData->pageStep = pData->maxPos - 2; |
printf("pageStep=%d\n",pData->pageStep); |
|
pData->barStart=0; /* start pixel of bar.*/ |
pData->barLen=MWM_MINBARLEN; /* length of bar.*/ |
pData->status=SBS_UNKNOWN; /* status of scroll bar.*/ |
#if 0 /* jmt: must handle WM_MOVE */ |
pData->rc=hwnd->winrect; /* screen coordinates position*/ |
#endif |
hwnd->userdata = (DWORD)pData; |
|
if (dwStyle == SBS_VERT) |
{ |
wndGetVScrollBarRect (hwnd, &rcBar); |
rcBar.left --; |
rcBar.right --; |
} |
else |
{ |
wndGetHScrollBarRect (hwnd, &rcBar); |
rcBar.top --; |
rcBar.bottom --; |
} |
/* adjust pData->barLen */ |
wndScrollBarPos (hwnd, dwStyle == SBS_HORZ, &rcBar); |
|
break; |
|
case WM_DESTROY: |
free ((void *)(hwnd->userdata)); |
break; |
|
case WM_PAINT: |
MwPaintScrollbars(hwnd,NULL,dwStyle); |
break; |
|
case WM_NCLBUTTONDOWN: |
case WM_NCLBUTTONDBLCLK: |
case WM_NCMOUSEMOVE: |
case WM_NCLBUTTONUP: |
MwHandleMessageScrollbar(hwnd, wParam, lParam, message, dwStyle); |
break; |
|
case WM_HSCROLL: |
case WM_VSCROLL: |
{ |
int newTop,itemCount,itemVisibles; |
|
pData = (MWSCROLLBARINFO *)hwnd->userdata; |
newTop = pData->curPos; |
itemCount = pData->maxPos - pData->minPos + 1; |
itemVisibles = pData->pageStep; |
|
switch(wParam) |
{ |
case SB_LINEDOWN: |
#define ITEM_BOTTOM(x) (x->curPos + itemVisibles - 1) |
if (ITEM_BOTTOM (pData) < (itemCount - 1 )) |
{ |
newTop ++; |
} |
break; |
|
case SB_LINEUP: |
if (pData->curPos > 0) |
{ |
newTop --; |
} |
break; |
|
case SB_PAGEDOWN: |
if ((pData->curPos + (itemVisibles << 1)) <= |
itemCount) |
newTop += itemVisibles; |
else |
newTop = itemCount - itemVisibles; |
|
if (newTop < 0) |
return 0; |
|
break; |
|
case SB_PAGEUP: |
if (pData->curPos >= itemVisibles) |
newTop -= itemVisibles; |
else |
newTop = 0; |
|
break; |
|
case SB_THUMBTRACK: |
newTop = (int)lParam; |
break; |
} |
|
pData->curPos = newTop; |
|
SendMessage (hwnd, WM_PAINT, 0, 0); |
|
sbSetScrollInfo (hwnd, pData, TRUE); |
|
return 0; |
} |
break; |
|
default: |
return DefWindowProc (hwnd, message, wParam, lParam); |
} |
return 0; |
} |
|
/graph3d.c
0,0 → 1,540
/* |
* Copyright (c) 1999 Greg Haerr <greg@censoft.com> |
* |
* 3D Graphics Library for Micro-Windows |
*/ |
#define MWINCLUDECOLORS |
#include "windows.h" |
#include "device.h" |
#include "graph3d.h" |
#define USEBLIT 1 /* =1 to use memDC's*/ |
|
static int nxpix; |
static int nypix; |
static vec1 xscale; |
static vec1 yscale; |
static vec3 eye; |
static vec3 direct; |
static double Q[5][5]; |
static HDC hdc; |
static HDC hdcMem; |
static HBITMAP hbmp, hbmpOrg; |
|
/* setup eye, direction, calc observation matrix Q*/ |
void |
look3(vec1 x, vec1 y, vec1 z) |
{ |
eye.x = x; |
eye.y = y; |
eye.z = z; |
direct.x = -eye.x; |
direct.y = -eye.y; |
direct.z = -eye.z; |
findQ(); |
} |
|
void |
init3(HDC hDC, HWND memhwnd) |
{ |
HBRUSH hbr; |
|
hdc = hDC; |
if(hdc) { |
nxpix = hdc->hwnd->clirect.right - hdc->hwnd->clirect.left; |
nypix = hdc->hwnd->clirect.bottom - hdc->hwnd->clirect.top; |
xscale = (vec1)(nxpix-1) / nxpix * nxpix/2; |
yscale = (vec1)(nypix-1) / nypix * nypix/2; |
|
if(memhwnd) { |
hdcMem = CreateCompatibleDC(NULL); |
if(hdcMem) { |
hbmp = CreateCompatibleBitmap(hdcMem, |
nxpix, nypix); |
hbmpOrg = SelectObject(hdcMem, hbmp); |
hdc = hdcMem; |
} |
hbr = (HBRUSH)GetClassLong(memhwnd, GCL_HBRBACKGROUND); |
FillRect(hdc, NULL, hbr); |
} |
/* create pen for setcolor3() color override*/ |
SelectObject(hdc, CreatePen(PS_SOLID, 1, BLACK)); |
} |
} |
|
void |
paint3(HDC hDC) |
{ |
if(hdcMem) { |
BitBlt(hDC, 0, 0, nxpix, nypix, hdcMem, 0, 0, SRCCOPY); |
DeleteObject(SelectObject(hdcMem, hbmpOrg)); |
DeleteDC(hdcMem); |
} |
hdcMem = NULL; |
} |
|
int |
fx(vec1 x) |
{ |
return (int)(x * xscale + nxpix*0.5 - 0.5); |
} |
|
int |
fy(vec1 y) |
{ |
return (int)(y * yscale + nypix*0.5 - 0.5); |
} |
|
void |
moveto3(vec2 pt) |
{ |
MoveToEx(hdc, fx(pt.x), fy(pt.y), NULL); |
} |
|
void |
setcolor3(MWCOLORVAL c) |
{ |
if(hdc) |
hdc->pen->color = c; |
} |
|
void |
lineto3(vec2 pt) |
{ |
LineTo(hdc, fx(pt.x), fy(pt.y)); |
} |
|
void |
polyfill(int n, vec2 points[]) |
{ |
int i; |
int xoff, yoff; |
MWPOINT pv[MAXPOLY]; |
|
if(!hdc) |
return; |
|
/* calc window offset*/ |
xoff = hdc->hwnd->clirect.left; |
yoff = hdc->hwnd->clirect.top; |
|
/* only plot non-trivial polygons*/ |
if(n > 2) { |
for(i=0; i<n; ++i) { |
pv[i].x = fx(points[i].x) + xoff; |
pv[i].y = fy(points[i].y) + yoff; |
/* fix: floating round error, y intercept difference |
* with GdLine |
*/ |
/*pv[i].x = fx(points[i].x + xoff);*/ |
/*pv[i].y = fy(points[i].y + yoff);*/ |
} |
GdSetForeground(GdFindColor(hdc->pen->color)); |
GdFillPoly(hdc->psd, n, pv); |
} |
} |
|
void |
square(void) |
{ |
vec2 pt0, pt1, pt2, pt3; |
|
pt0.x = -1; pt0.y = 1; |
pt1.x = -1; pt1.y = -1; |
pt2.x = 1; pt2.y = -1; |
pt3.x = 1; pt3.y = 1; |
moveto3(pt0); |
lineto3(pt1); |
lineto3(pt2); |
lineto3(pt3); |
lineto3(pt0); |
} |
|
void |
circle3(vec1 r) |
{ |
vec1 theta = 0; |
vec1 thinc = 2*pi/100; |
int i; |
vec2 pt; |
|
pt.x = r; |
pt.y = 0.0; |
moveto3(pt); |
|
for(i=0; i<100; ++i) { |
theta = theta + thinc; |
pt.x = r*cos(theta); |
pt.y = r*sin(theta); |
lineto3(pt); |
} |
} |
|
void |
daisy(vec1 r,int points) |
{ |
int i, j; |
vec1 theta = 0; |
vec1 thinc; |
vec2 pt[100]; |
|
/* calculate n points on a circle*/ |
thinc = 2*pi/points; |
for(i=0; i<points; ++i) { |
pt[i].x = r*cos(theta); |
pt[i].y = r*sin(theta); |
theta += thinc; |
} |
|
/* join point i to point j for all 0 <= i < j < n */ |
for(i=0; i<points-1; ++i) { |
for(j=i+1; j<points; ++j) { |
moveto3(pt[i]); |
lineto3(pt[j]); |
} |
} |
} |
|
void |
rose(vec1 r,int levels,int points) |
{ |
int i, j, m, n; |
vec1 r1, theta, thinc; |
vec2 inner[100]; |
vec2 outer[100]; |
vec2 triangle[3]; |
|
m = levels; |
n = points; |
thinc = 2*pi/n; |
|
/* initial inner circle*/ |
for(i=0; i<n; ++i) { |
inner[i].x = 0.0; |
inner[i].y = 0.0; |
} |
|
/* loop thru m levels*/ |
for(j=1; j<=m; ++j) { |
theta = -j*pi/n; |
r1 = r * (vec1)j/m; |
|
/* calc n points on outer circle*/ |
for(i=0; i<n; ++i) { |
theta += thinc; |
outer[i].x = r1*cos(theta); |
outer[i].y = r1*sin(theta); |
} |
|
/* construct/draw triangles with vertices on |
* inner and outer circles |
*/ |
for(i=0; i<n; ++i) { |
triangle[0] = outer[i]; |
triangle[1] = outer[(i+1) % n]; |
triangle[2] = inner[i]; |
|
/* fill triangle in red*/ |
setcolor3(RED); |
polyfill(3, triangle); |
|
#if 1 |
/* outline triangle in white*/ |
setcolor3(WHITE); |
moveto3(triangle[0]); |
lineto3(triangle[1]); |
lineto3(triangle[2]); |
lineto3(triangle[0]); |
#endif |
} |
|
/* copy points on outer circle to inner arrays*/ |
for(i=0; i<n; ++i) |
inner[i] = outer[i]; |
} |
} |
|
/* draw a triangle with cordners v0, v1, v2*/ |
void |
triangle(vec2 v0, vec2 v1, vec2 v2) |
{ |
vec2 poly[3]; |
|
poly[0] = v0; |
poly[1] = v1; |
poly[2] = v2; |
|
setcolor3(GREEN); |
polyfill(3, poly); |
setcolor3(BLACK); |
moveto3(poly[2]); |
lineto3(poly[0]); |
lineto3(poly[1]); |
lineto3(poly[2]); |
} |
|
/* draw a quadrilateral with corners v0, v1, v2, v3*/ |
void |
quadrilateral(vec2 v0, vec2 v1, vec2 v2, vec2 v3) |
{ |
vec2 poly[4]; |
|
poly[0] = v0; |
poly[1] = v1; |
poly[2] = v2; |
poly[3] = v3; |
setcolor3(GREEN); |
polyfill(4, poly); |
setcolor3(BLACK); |
moveto3(poly[3]); |
lineto3(poly[0]); |
lineto3(poly[1]); |
lineto3(poly[2]); |
lineto3(poly[3]); |
} |
|
/* find intersection of lines v0 to v1 and v2 to v3*/ |
static int |
patch(vec2 v0, vec2 v1, vec2 v2, vec2 v3) |
{ |
vec1 denom; |
vec1 mu; |
vec2 v4; |
|
denom = (v1.x-v0.x)*(v3.y-v2.y) - (v1.y-v0.y)*(v3.x-v2.x); |
if(fabs(denom) > epsilon) { |
mu = ((v2.x-v0.x)*(v3.y-v2.y) - (v2.y-v0.y)*(v3.x-v2.x))/denom; |
|
/* if intersection between lines v0 to v1 and v2 to v3, |
* call it v4 and form triangles v0,v2,v4 and v1,v3,v4 |
*/ |
if(mu >= 0 && mu <= 1) { |
v4.x = (1-mu)*v0.x + mu*v1.x; |
v4.y = (1-mu)*v0.y + mu*v1.y; |
triangle(v0, v2, v4); |
triangle(v1, v3, v4); |
return 0; |
} |
} |
|
/* else find intersection of lines v0 to v2 and v1 to v3*/ |
denom = (v2.x-v0.x)*(v3.y-v1.y) - (v2.y-v0.y)*(v3.x-v1.x); |
if(fabs(denom) > epsilon) { |
mu = ((v1.x-v0.x)*(v3.y-v1.y) - (v1.y-v0.y)*(v3.x-v1.x))/denom; |
|
/* if intersection between v0 and v1, call it v4 |
* and form triangles v0,v1,v4 and v2,v3,v4 |
*/ |
if(mu >= 0 && mu <= 1) { |
v4.x = (1-mu)*v0.x + mu*v2.x; |
v4.y = (1-mu)*v0.y + mu*v2.y; |
triangle(v0, v1, v4); |
triangle(v2, v3, v4); |
return 0; |
} |
} |
|
/* there are no proper intersections so form quadrilateral v0,v1,v3,v2*/ |
quadrilateral(v0, v1, v3, v2); |
return 1; |
} |
|
/* plotted function*/ |
static vec1 |
plotfn(vec1 x, vec1 z) |
{ |
vec1 t; |
|
/* y = 4sin(sqrt(x*x+z*z))/sqrt(x*x+z*z) */ |
t = sqrt(x*x + z*z); |
if(fabs(t) < epsilon) |
return 4.0; |
return 4.0 * sin(t) / t; |
} |
|
/* draw mathematical function plotfn*/ |
void |
drawgrid(vec1 xmin, vec1 xmax, int nx, vec1 zmin, vec1 zmax, int nz) |
{ |
int i, j; |
vec1 xi, xstep, yij; |
vec1 zj, zstep; |
vec2 v[2][100]; |
double S[5][5]; |
|
/* scale it down*/ |
scale3(1.0/(xmax-xmin)*2, 1.0/(xmax-xmin)*2, 1.0/(zmax-zmin), S); |
mult3(Q, S, Q); |
|
/* grid from xmin to xmax in nx steps and zmin to xmax in nz steps*/ |
xstep = (xmax-xmin)/nx; |
zstep = (zmax-zmin)/nz; |
xi = xmin; |
zj = zmin; |
|
/* calc grid points on first fixed-z line, fine the y-height |
* and transfrorm the points (xi,yij,zj) into observed |
* position. Observed first set stored in v[0,1..nx] |
*/ |
for(i=0; i<=nx; ++i) { |
yij = plotfn(xi, zj); |
v[0][i].x = Q[1][1]*xi + Q[1][2]*yij + Q[1][3]*zj; |
v[0][i].y = Q[2][1]*xi + Q[2][2]*yij + Q[2][3]*zj; |
xi += xstep; |
} |
|
/* run thru consecutive fixed-z lines (the second set)*/ |
for(j=0; j<nz; ++j) { |
xi = xmin; |
zj += zstep; |
|
/* calc grid points on this second set, find the |
* y-height and transform the points (xi,yij,zj) |
* into observed position. Observed second set |
* stored in v[1,0..nx] |
*/ |
for(i=0; i<=nx; ++i) { |
yij = plotfn(xi, zj); |
v[1][i].x = Q[1][1]*xi + Q[1][2]*yij + Q[1][3]*zj; |
v[1][i].y = Q[2][1]*xi + Q[2][2]*yij + Q[2][3]*zj; |
xi += xstep; |
} |
|
/* run thru the nx patches formed by these two sets*/ |
for(i=0; i<nx; ++i) |
patch(v[0][i], v[0][i+1], v[1][i], v[1][i+1]); |
|
/* copy second set into first set*/ |
for(i=0; i<=nx; ++i) |
v[0][i] = v[1][i]; |
} |
} |
|
/* returns the angle whose tangent is y/x. |
* all anomalies such as x=0 are also checked |
*/ |
vec1 |
angle(vec1 x, vec1 y) |
{ |
if(fabs(x) < epsilon) |
if(fabs(y) < epsilon) |
return 0.0; |
else |
if(y > 0.0) |
return pi*0.5; |
else return pi*1.5; |
else |
if(x < 0.0) |
return atan(y/x) + pi; |
else return atan(y/x); |
} |
|
/* calc 3d scaling matrix A giving scaling vector sx,sy,sz. |
* one unit on the x axis becomes sx units, one unit on y, sy, |
* and one unit on the z axis becomes sz units |
*/ |
void |
scale3(vec1 sx, vec1 sy, vec1 sz, double A[][5]) |
{ |
int i, j; |
|
for(i=1; i<5; ++i) |
for(j=1; j<5; ++j) |
A[i][j] = 0.0; |
A[1][1] = sx; |
A[2][2] = sy; |
A[3][3] = sz; |
A[4][4] = 1.0; |
} |
|
/* calc 3d axes translation matrix A |
* origin translated by vectdor tx,ty,tz |
*/ |
void |
tran3(vec1 tx, vec1 ty, vec1 tz, double A[][5]) |
{ |
int i, j; |
|
for(i=1; i<5; ++i) { |
for(j=1; j<5; ++j) |
A[i][j] = 0.0; |
A[i][i] = 1.0; |
} |
A[1][4] = -tx; |
A[2][4] = -ty; |
A[3][4] = -tz; |
} |
|
/* calc 3d axes rotation matrix A. The axes are |
* rotated anti-clockwise through an angle theta radians |
* about an axis specified by m: m=1 means x, m=2 y, m=3 z axis |
*/ |
void |
rot3(int m, vec1 theta, double A[][5]) |
{ |
int i, j, m1, m2; |
vec1 c, s; |
|
for(i=1; i<5; ++i) |
for(j=1; j<5; ++j) |
A[i][j] = 0.0; |
A[m][m] = 1.0; |
A[4][4] = 1.0; |
m1 = (m % 3) + 1; |
m2 = (m1 % 3) + 1; |
c = cos(theta); |
s = sin(theta); |
A[m1][m1] = c; |
A[m2][m2] = c; |
A[m1][m2] = s; |
A[m2][m1] = s; |
} |
|
/* calc the matrix product C of two matrices A and B*/ |
void |
mult3(double A[][5], double B[][5], double C[][5]) |
{ |
int i, j, k; |
vec1 ab; |
|
for(i=1; i<5; ++i) |
for(j=1; j<5; ++j) { |
ab = 0; |
for(k=1; k<5; ++k) |
ab += A[i][k] * B[k][j]; |
C[i][j] = ab; |
} |
} |
|
/* calc observation matrix Q for given observer*/ |
void |
findQ(void) |
{ |
vec1 alpha, beta, gamma, v, w; |
double E[5][5]; |
double F[5][5]; |
double G[5][5]; |
double H[5][5]; |
double U[5][5]; |
|
/* calc translation matrix F*/ |
tran3(eye.x, eye.y, eye.z, F); |
|
/* calc rotation matrix G*/ |
alpha = angle(-direct.x, -direct.y); |
rot3(3, alpha, G); |
|
/* calc rotation matrix H*/ |
v = sqrt(direct.x*direct.x + direct.y*direct.y); |
beta = angle(-direct.z, v); |
rot3(2, beta, H); |
|
/* calc rotation matrix U*/ |
w = sqrt(v*v + direct.z*direct.z); |
gamma = angle(-direct.x*w, direct.y*direct.z); |
rot3(3, -gamma, U); |
|
/* combine the transformations to find Q*/ |
mult3(G, F, Q); |
mult3(H, Q, E); |
mult3(U, E, Q); |
} |
/Makefile
0,0 → 1,50
############################################################################## |
# Microwindows template Makefile |
# Copyright (c) 2000 Martin Jolicoeur, Greg Haerr |
############################################################################## |
|
ifndef TOP |
TOP = ../.. |
CONFIG = $(TOP)/config |
endif |
|
include $(CONFIG) |
|
######################## Additional Flags section ############################ |
|
# Directories list for header files |
INCLUDEDIRS += |
# Defines for preprocessor |
DEFINES += |
|
# Compilation flags for C files OTHER than include directories |
CFLAGS += |
# Preprocessor flags OTHER than defines |
CPPFLAGS += |
# Linking flags |
LDFLAGS += |
|
############################# targets section ################################ |
|
ifeq ($(MICROWIN), Y) |
|
# If you want to create a library with the objects files, define the name here |
LIBNAME = libmwinlib.a |
LIBNAMESO = libmwinlib.so |
|
# List of objects to compile |
OBJS = draw3d.o ptinsid.o insetr.o fastfill.o graph3d.o mwuser.o |
|
ifneq ($(ARCH), ELKS) |
OBJS += button.o edit.o listbox.o progbar.o static.o combobox.o caret.o \ |
scrlbar.o medit.o |
endif |
|
endif |
|
######################### Makefile.rules section ############################# |
|
include $(TOP)/Makefile.rules |
|
######################## Tools targets section ############################### |
|
/progbar.c
0,0 → 1,363
/* |
* Copyright (C) 1999, 2000, Wei Yongming. |
* Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com> |
* |
* Progress bar for Microwindows win32 api. |
*/ |
|
/* |
** This library is free software; you can redistribute it and/or |
** modify it under the terms of the GNU Library General Public |
** License as published by the Free Software Foundation; either |
** version 2 of the License, or (at your option) any later version. |
** |
** This library is distributed in the hope that it will be useful, |
** but WITHOUT ANY WARRANTY; without even the implied warranty of |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
** Library General Public License for more details. |
** |
** You should have received a copy of the GNU Library General Public |
** License along with this library; if not, write to the Free |
** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
** MA 02111-1307, USA |
*/ |
|
/* |
** Alternatively, the contents of this file may be used under the terms |
** of the Mozilla Public License (the "MPL License") in which case the |
** provisions of the MPL License are applicable instead of those above. |
*/ |
|
/* Copyright (C) 1999, 2000, Wei Yongming. |
** |
** Note: |
** Originally by Zhao Jianghua. |
** |
** Create date: 1999/8/29 |
** |
** Modify records: |
** |
** Who When Where For What Status |
**----------------------------------------------------------------------------- |
** WEI Yongming 1999/10/27 Tsinghua unsigned int Finished |
** WEI Yongming 1999/10/27 Tsinghua FPException fixing Finished |
** WEI Yongming 2000/02/24 Tsinghua Add MPL License Finished |
** Kevin Tseng 2000/05/24 gv port to microwin ported |
** Greg Haerr 2000/06/15 Utah removed floats Finished |
*/ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#define MWINCLUDECOLORS |
#include "windows.h" /* windef.h, winuser.h */ |
#include "wintools.h" /* Draw3dBox */ |
#include "device.h" /* GdGetTextSize */ |
|
#define TEST 1 /* =1 for testing*/ |
|
#define WIDTH_PBAR_BORDER 2 |
|
typedef struct _PROGRESSDATA { |
unsigned int nMin; |
unsigned int nMax; |
unsigned int nPos; |
unsigned int nStepInc; |
} PROGRESSDATA, *PPROGRESSDATA; |
|
static LRESULT CALLBACK |
ProgressBarCtrlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); |
|
int WINAPI MwRegisterProgressBarControl(HINSTANCE hInstance) |
{ |
WNDCLASS wc; |
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; |
wc.lpfnWndProc = (WNDPROC)ProgressBarCtrlProc; |
wc.cbClsExtra = 0; |
wc.cbWndExtra = 0; |
wc.hInstance = hInstance; |
wc.hIcon = NULL; |
wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/ |
wc.hbrBackground= GetStockObject(LTGRAY_BRUSH); |
wc.lpszMenuName = NULL; |
wc.lpszClassName= "PROGBAR"; |
|
return RegisterClass(&wc); |
} |
|
static void |
FillBox(HDC hdc, int x, int y, int w, int h, COLORREF cr) |
{ |
RECT rc; |
|
if (w <= 0) |
return; |
SetRect(&rc, x, y, x+w, y+h); |
FastFillRect(hdc, &rc, cr); |
} |
|
static int |
GetSysCharWidth(HDC hdc) |
{ |
int cw, ch, cb; |
|
GdGetTextSize(hdc->font->pfont,"X",1, &cw,&ch,&cb,MWTF_ASCII); |
return cw; |
} |
|
static int |
GetSysCharHeight(HDC hdc) |
{ |
int cw, ch, cb; |
|
GdGetTextSize(hdc->font->pfont,"X",1, &cw,&ch,&cb,MWTF_ASCII); |
return ch; |
} |
|
void pbarOnDraw (HWND hwnd, HDC hdc, PROGRESSDATA* pData, BOOL fVertical, |
BOOL fErase) |
{ |
int x, y, w, h; |
unsigned int nAllPart; |
unsigned int nNowPart; |
int whOne, nRem; |
int ix, iy; |
int i; |
int step; |
COLORREF cr; |
RECT rcClient; |
char szText[8]; |
|
if (!hdc || (pData->nMax == pData->nMin)) |
return; |
|
if ((pData->nMax - pData->nMin) > 5) |
step = 5; |
else |
step = 1; |
|
GetClientRect (hwnd, &rcClient); |
SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); |
|
x = rcClient.left + WIDTH_PBAR_BORDER; |
y = rcClient.top + WIDTH_PBAR_BORDER; |
w = (rcClient.right - rcClient.left) - (WIDTH_PBAR_BORDER << 1); |
h = (rcClient.bottom - rcClient.top) - (WIDTH_PBAR_BORDER << 1); |
|
nAllPart = (pData->nMax - pData->nMin) / step; |
nNowPart = (pData->nPos - pData->nMin) / step; |
if (fVertical) { |
whOne = h / nAllPart; |
nRem = h % nAllPart; |
} else { |
whOne = w / nAllPart; |
nRem = w % nAllPart; |
} |
|
if (fErase) |
FillBox (hdc, x, y, w, h, GetSysColor(COLOR_BTNSHADOW)); |
|
if(whOne >= 4) { |
if (fVertical) { |
for (i = 0, iy = y + h - 1; i < nNowPart; ++i) { |
#if 0 |
if ((iy - whOne) < y) |
whOne = iy - y; |
#endif |
|
FillBox (hdc, x, iy - whOne, w, whOne - 1, BLUE); |
|
iy -= whOne + 1; |
#if 0 |
if(nRem > 0) { |
iy --; |
nRem --; |
} |
#endif |
} |
} |
else { |
for (i = 0, ix = x + 1; i < nNowPart; ++i) { |
#if 0 |
if ((ix + whOne) > (x + w)) |
whOne = x + w - ix; |
#endif |
FillBox (hdc, ix, y, whOne - 1, h, BLUE); |
ix += whOne + 1; |
#if 0 |
if(nRem > 0) { |
ix ++; |
nRem --; |
} |
#endif |
} |
} |
} |
else { |
/* no vertical support */ |
int d = nNowPart*100/nAllPart; |
int maxw = GetSysCharWidth (hdc) << 2; |
int charh = GetSysCharHeight (hdc); |
|
if (d > 50) |
cr = BLUE; |
else |
cr = GetSysColor(COLOR_BTNSHADOW); |
FillBox (hdc, x + ((w - maxw)>>1), y + ((h - charh) > 1), maxw, |
charh - 1, cr); |
FillBox (hdc, x, y, (int)((long)w*d/100L), h, BLUE); |
SetTextColor (hdc, WHITE); |
SetBkMode (hdc, TRANSPARENT); |
sprintf (szText, "%d%%", d); |
TextOut (hdc, x + ((w - GetSysCharWidth (hdc) * strlen (szText) )>>1), |
y + ((h - GetSysCharHeight(hdc) )>>1), |
szText, strlen(szText)); |
} |
} |
|
static void pbarNormalizeParams (const HWND pCtrl, |
PROGRESSDATA* pData, BOOL fNotify) |
{ |
if (pData->nPos > pData->nMax) { |
if (fNotify) |
SendMessage (GetParent ((HWND)pCtrl), WM_COMMAND, |
(WPARAM)MAKELONG (pCtrl->id, PBN_REACHMAX), (LPARAM)pCtrl); |
pData->nPos = pData->nMax; |
} |
|
if (pData->nPos < pData->nMin) { |
if (fNotify) |
SendMessage (GetParent ((HWND)pCtrl), WM_COMMAND, |
(WPARAM)MAKELONG (pCtrl->id, PBN_REACHMIN), (LPARAM)pCtrl); |
pData->nPos = pData->nMin; |
} |
} |
|
static LRESULT CALLBACK |
ProgressBarCtrlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) |
{ |
HDC hdc; |
HWND pCtrl; |
PROGRESSDATA* pData; |
BOOL fErase; |
RECT rc; |
PAINTSTRUCT ps; |
int pos; |
|
pCtrl = hwnd; |
|
switch (message) |
{ |
case WM_CREATE: |
if (!(pData = malloc (sizeof (PROGRESSDATA)))) { |
fprintf(stderr, "Create progress bar control failure!\n"); |
return -1; |
} |
|
#if TEST |
pData->nMax = 1000; |
pData->nMin = 0; |
pData->nPos = 500; |
pData->nStepInc = 100; |
#else |
pData->nMax = 100; |
pData->nMin = 0; |
pData->nPos = 0; |
pData->nStepInc = 10; |
#endif |
|
pCtrl->userdata = (DWORD)pData; |
break; |
|
case WM_DESTROY: |
free ((void *)(pCtrl->userdata)); |
break; |
|
case WM_GETDLGCODE: |
return DLGC_STATIC; |
|
case WM_NCPAINT: |
if(GetWindowLong(hwnd, GWL_STYLE) & WS_BORDER) { |
GetWindowRect(hwnd, &rc); |
hdc = GetWindowDC(hwnd); |
Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, |
rc.bottom-rc.top, GetSysColor(COLOR_BTNSHADOW), |
GetSysColor(COLOR_BTNHIGHLIGHT)); |
} |
break; |
|
case WM_PAINT: |
hdc = BeginPaint (hwnd,&ps); |
pbarOnDraw (hwnd, hdc, (PROGRESSDATA *)pCtrl->userdata, |
hwnd->style & PBS_VERTICAL, TRUE); |
EndPaint (hwnd, &ps); |
break; |
|
case PBM_SETRANGE: |
pData = (PROGRESSDATA *)pCtrl->userdata; |
pData->nMin = min (wParam, lParam); |
pData->nMax = max (wParam, lParam); |
if (pData->nPos > pData->nMax) |
pData->nPos = pData->nMax; |
if (pData->nPos < pData->nMin) |
pData->nPos = pData->nMin; |
break; |
|
case PBM_SETSTEP: |
pData = (PROGRESSDATA *)pCtrl->userdata; |
pData->nStepInc = wParam; |
break; |
|
case PBM_SETPOS: |
pData = (PROGRESSDATA *)pCtrl->userdata; |
|
if (pData->nPos == wParam) |
break; |
|
fErase = (wParam < pData->nPos); |
pData->nPos = wParam; |
pbarNormalizeParams (pCtrl, pData, hwnd->style & PBS_NOTIFY); |
InvalidateRect(hwnd, NULL, fErase); |
break; |
|
case PBM_DELTAPOS: |
pData = (PROGRESSDATA *)pCtrl->userdata; |
|
if (wParam == 0) |
break; |
|
fErase = (wParam < 0); |
pData->nPos += wParam; |
pbarNormalizeParams (pCtrl, pData, hwnd->style & PBS_NOTIFY); |
InvalidateRect(hwnd, NULL, fErase); |
break; |
|
case PBM_STEPIT: |
pData = (PROGRESSDATA *)pCtrl->userdata; |
|
if (pData->nStepInc == 0) |
break; |
|
fErase = (pData->nStepInc < 0); |
pData->nPos += pData->nStepInc; |
pbarNormalizeParams (pCtrl, pData, hwnd->style & PBS_NOTIFY); |
InvalidateRect(hwnd, NULL, fErase); |
break; |
|
#if TEST |
case WM_LBUTTONDOWN: |
case WM_LBUTTONDBLCLK: |
pData = (PROGRESSDATA *)pCtrl->userdata; |
pos = pData->nPos; |
pos += pData->nStepInc; |
if (pos > pData->nMax) |
pos = pData->nMin; |
SendMessage(hwnd, PBM_SETPOS, pos, 0L); |
break; |
#endif |
default: |
return DefWindowProc (hwnd, message, wParam, lParam); |
} |
return 0; |
} |