/**
*
* 文 件 名:WEdit.c
*
* 描 述:
*
* 创 建 者:赵平智 <[email protected]>
*
* 创建日期:20091116
*
* 备 注:
*
*
* * 维护历史 *
*
* <日期> <修改者>
* <修改内容...>
*
**/
#include "WEdit.h"
#include "../WDialog/WDialog.h"
#include "../WScrollBar/WScrollBar.h"
#define MOVE_CARET_TO_PREVCHARACTER 0x00000001
#define MOVE_CARET_TO_NEXTCHARACTER 0x00000002
#define MOVE_CARET_TO_PREVROW 0x00000004
#define MOVE_CARET_TO_NEXTROW 0x00000008
#define MOVE_CARET_TO_ROWBEGINNING 0x00000010
#define MOVE_CARET_TO_ROWEND 0x00000020
#define SET_CARETPOS_BY_POINT 0x00000040
#define DELETE_CHARACTER 0x00000080
VOID TOG_WEdit(OBJECT* pObj);
static void Prepaint(OBJECT* This, HBITMAP hBitmap);
static void Paint(OBJECT* This, HBITMAP hBitmap, const VR* pCaller);
static void CalculateText(OBJECT* This, const VR* pCaller);
static void MakeCaretVisible(OBJECT* This);
static void MakeCaretInvisible(OBJECT* This);
static void SetCaretPosByPoint(OBJECT* This, POINT pt);
static void SetCaretPosBYnCaretChar(OBJECT* This, const UI32 flag);
static void MoveCaretToPrevCharacter(OBJECT* This);
static void MoveCaretToNextCharacter(OBJECT* This);
static void MoveCaretToPrevRow(OBJECT* This);
static void MoveCaretToNextRow(OBJECT* This);
static void MoveCaretToRowBeginning(OBJECT* This);
static void MoveCaretToRowEnd(OBJECT* This);
static void Delete(OBJECT* This, int iFirst, int iLast, const VR* pCaller);
static void WriteText(OBJECT* This, const VR* pCaller);
/*=====================+ OICC label +====================*/
/*<oicc>*/
/*<ibn> WControl </ibn>*/
/*<crt>*/
FRESULT CRT_WEdit(OBJID* pOID, BYTKTY IQCty, BYTKTY OQCty, SI32 NumCR, OBJECT** ppObj, BYTE* pExotic)
{
extern VOID InitAIBofND(OBJECT* pND, MLDSN* pMsn, NUMIB nib);
extern VOID InitABNofND(OBJECT* pND, MLDSN* pMsn, NUMBN nbn);
extern VOID TOG_WControl(OBJECT* pObj);
extern VOID TOG_WGrinterface(OBJECT* pObj);
extern VOID TOG_OIOIC(OBJECT* pObj);
UI32 ux_ND = 4; /* ND数量。*/
UI32 ux_BN = 6; /* 各ND的BN数量之和。*/
UI32 ux_IB = 3; /* 各ND的IBN数量之和。*/
UI32 ux_CS = NumCR * 10; /* 各ND的最少CS数量之和。*/
UI32 ux_EM = sizeof(EM_WEDIT) + sizeof(EM_WEDIT) + sizeof(EM_WGRINTERFACE)
+ sizeof(EM_OIOIC); /* 各ND的EM尺寸之和。*/
UI32 sum = ux_ND * sizeof(OBJECT) /* for AND. */
+ ux_BN * sizeof(OBJECT*) /* for "ppo_ABN". */
+ ux_IB * sizeof(OBJECT*) /* for "ppo_AIB". */
+ ux_CS * sizeof(VR) + ux_EM; /* for "pvr_ACS" and "pEM". */
BYTE* pIC = NULL;
if(NULL == pExotic)
{
*ppObj = NULL;
pIC = (BYTE*)calloc(sum, 1);
}else
{
pIC = pExotic;
}
if( pIC != NULL )
{
OBJECT* pND;
MLDSN ArrMsn[3];
BYTE* p = pIC + sizeof(OBJECT) * ux_ND;
/*** 确定AND各元素 ***/
/** WEdit **/
pND = (OBJECT*)pIC;
TOG_WEdit(pND);
pND->MSN = MSN_WEDIT;
pND->OID = (*pOID)++;
pND->po_AND = (OBJECT*)pIC;
pND->NND = ux_ND;
/** WControl **/
TOG_WControl(++pND);
pND->MSN = MSN_WCONTROL;
pND->OID = (*pOID)++;
pND->po_AND = (OBJECT*)pIC;
pND->NND = ux_ND;
/** WGrinterface **/
TOG_WGrinterface(++pND);
pND->MSN = MSN_WGRINTERFACE;
pND->OID = (*pOID)++;
pND->po_AND = (OBJECT*)pIC;
pND->NND = ux_ND;
/** OIOIC **/
TOG_OIOIC(++pND);
pND->MSN = MSN_OIOIC;
pND->OID = (*pOID)++;
pND->po_AND = (OBJECT*)pIC;
pND->NND = ux_ND;
/*** 初始化各ND ***/
/** WEdit **/
pND = (OBJECT*)pIC;
/* - AIB - */
pND->ppo_AIB = (OBJECT**)p;
ArrMsn[0] = MSN_WCONTROL;
InitAIBofND(pND, ArrMsn, 1);
p += sizeof(OBJECT*) * 1;
/* - ABN - */
pND->ppo_ABN = (OBJECT**)p;
ArrMsn[0] = MSN_WCONTROL;
ArrMsn[1] = MSN_WGRINTERFACE;
ArrMsn[2] = MSN_OIOIC;
InitABNofND(pND, ArrMsn, 3);
p += sizeof(OBJECT*) * 3;
/* - ACS - */
pND->pvr_ACS = (VR*)p;
pND->NCS = NumCR * 1;
p += sizeof(VR) * pND->NCS;
/* - EM - */
pND->pEM = (EM*)p;
p += sizeof(EM_WEDIT);
/** WControl **/
++pND;
/* - AIB - */
pND->ppo_AIB = (OBJECT**)p;
ArrMsn[0] = MSN_WGRINTERFACE;
InitAIBofND(pND, ArrMsn, 1);
p += sizeof(OBJECT*) * 1;
/* - ABN - */
pND->ppo_ABN = (OBJECT**)p;
ArrMsn[0] = MSN_WGRINTERFACE;
ArrMsn[1] = MSN_OIOIC;
InitABNofND(pND, ArrMsn, 2);
p += sizeof(OBJECT*) * 2;
/* - ACS - */
pND->pvr_ACS = (VR*)p;
pND->NCS = NumCR * 2;
p += sizeof(VR) * pND->NCS;
/* - EM - */
pND->pEM = (EM*)p;
p += sizeof(EM_WEDIT);
/** WGrinterface **/
++pND;
/* - AIB - */
pND->ppo_AIB = (OBJECT**)p;
ArrMsn[0] = MSN_OIOIC;
InitAIBofND(pND, ArrMsn, 1);
p += sizeof(OBJECT*) * 1;
/* - ABN - */
pND->ppo_ABN = (OBJECT**)p;
ArrMsn[0] = MSN_OIOIC;
InitABNofND(pND, ArrMsn, 1);
p += sizeof(OBJECT*) * 1;
/* - ACS - */
pND->pvr_ACS = (VR*)p;
pND->NCS = NumCR * 3;
p += sizeof(VR) * pND->NCS;
/* - EM - */
pND->pEM = (EM*)p;
p += sizeof(EM_WGRINTERFACE);
/** OIOIC **/
++pND;
/* - ACS - */
pND->pvr_ACS = (VR*)p;
pND->NCS = NumCR * 4;
p += sizeof(VR) * pND->NCS;
/* - EM - */
pND->pEM = (EM*)p;
if( IQCty > 0 )
{
/* - IQ - */
((EM_OIOIC*)(pND->pEM))->IQ.Dtrm = (BYTE*)calloc(IQCty, 1);
if( NULL == ((EM_OIOIC*)(pND->pEM))->IQ.Dtrm)
{
/* 分配IQ的容量失败!*/
if(NULL == pExotic)
free(pIC);
return FR_N;
}
((EM_OIOIC*)(pND->pEM))->IQ.Front = ((EM_OIOIC*)(pND->pEM))->IQ.Rear = ((EM_OIOIC*)(pND->pEM))->IQ.Dtrm - 1;
((EM_OIOIC*)(pND->pEM))->IQ.Cty = IQCty;
((EM_OIOIC*)(pND->pEM))->IQ.Qty = ((EM_OIOIC*)(pND->pEM))->IQ.Lost = 0;
}
if( OQCty > 0 )
{
/* - OQ - */
((EM_OIOIC*)(pND->pEM))->OQ.Dtrm = (BYTE*)calloc(OQCty, 1);
if(NULL == ((EM_OIOIC*)(pND->pEM))->OQ.Dtrm)
{
/* 分配OQ的容量失败!*/
if( ((EM_OIOIC*)(pND->pEM))->IQ.Dtrm != NULL )
free(((EM_OIOIC*)(pND->pEM))->IQ.Dtrm);
if(NULL == pExotic)
free(pIC);
return FR_N;
}
((EM_OIOIC*)(pND->pEM))->OQ.Front = ((EM_OIOIC*)(pND->pEM))->OQ.Rear = ((EM_OIOIC*)(pND->pEM))->OQ.Dtrm - 1;
((EM_OIOIC*)(pND->pEM))->OQ.Cty = OQCty;
((EM_OIOIC*)(pND->pEM))->OQ.Qty = ((EM_OIOIC*)(pND->pEM))->OQ.Lost = 0;
}
p += sizeof(EM_OIOIC);
}else
{
return FR_N;
}
if(NULL == pExotic)
*ppObj = (OBJECT*)pIC;
return FR_P;
}
/*</crt>*/
/*</oicc>*/
/*=====================+ Interface +=====================*/
/**
*
* 名称:WEdit_Open
*/
static IRESULT WEdit_Open(OBJECT* This, const VR* pCaller)
{
EM_WEDIT* pem;
OBS_OBJECT_OPEN_;
/* 在下面完成接口自己的任务。*/
if(1 == This->RefCnt)
{
pem = (EM_WEDIT*)This->pEM;
pem->pWGrinterface = GetBN(This, MSN_WGRINTERFACE);
pem->pWControl = GetBN(This, MSN_WCONTROL);
}
return IR_P;
}
/**
*
* 名称:WEdit_Input
*/
static IRESULT WEdit_Input(OBJECT* This, BYTE* IStrm, BYTKTY Qty, const VR* pCaller)
{
/* ... */
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_INPUT;
}
/**
*
* 名称:WEdit_Output
*/
static IRESULT WEdit_Output(OBJECT* This, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
/* ... */
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_OUTPUT;
}
/**
*
* 名称:WEdit_IOput
*/
static IRESULT WEdit_IOput(OBJECT* This, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
/* ... */
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_IOPUT;
}
/**
*
* 名称:WEdit_Interact0
*/
static IRESULT WEdit_Interact0(OBJECT* This, ACTION Act, const VR* pCaller)
{
VR caller;
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WPANEL* pem_parwpa;
HFONT hOldFont;
HDC hdc;
TEXTMETRIC tm;
caller.cr = pCaller->cr;
caller.mr = This->OID;
switch(Act)
{
case CMD_PREPARE:
if(pem->cpty > 0)
{
pem->pAPWC = (POINT*)calloc(pem->cpty, sizeof(POINT));
if(NULL == pem->pAPWC)
return IR_N;
}
pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
hdc = GetDC(pem_parwpa->hWnd);
if(pem->font)
hOldFont = SelectObject(hdc, pem->font);
// Get the metrics of the current font.
GetTextMetrics(hdc, &tm);
if(pem->font)
SelectObject(hdc, hOldFont);
ReleaseDC(pem_parwpa->hWnd, hdc);
pem->CharHeight = tm.tmHeight;
CalculateText(This, &caller);
return IR_P;
case CMD_WGI_PREPAINT:
Prepaint(This, NULL);
return IR_P;
case CMD_WGI_PAINT0:
Paint(This, NULL, &caller);
return IR_P;
case CLR_WGI_TEXT:
VO_Interact0(pem->pWGrinterface, CLR_WGI_TEXT, &caller);
Paint(This, NULL, &caller);
return IR_P;
default:
break;
}
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_INTERACT0;
}
/**
*
* 名称:WEdit_Interact1
*/
static IRESULT WEdit_Interact1(OBJECT* This, ACTION Act, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
/* ... */
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_INTERACT1;
}
/**
*
* 名称:WEdit_Interact2
*/
static IRESULT WEdit_Interact2(OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, const VR* pCaller)
{
VR caller;
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WEDIT* pem_wct = (EM_WEDIT*)pem->pWControl->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WGRINTERFACE* pem_parwgr;
EM_WPANEL* pem_parwpa;
EM_WDIALOG* pem_parwdl;
EM_WGRINTERFACE* pem_sbwgr;
HFONT hOldFont;
INIT_WEDIT* piwed;
HDC hdc;
TEXTMETRIC tm;
caller.cr = pCaller->cr;
caller.mr = This->OID;
switch(Act)
{
case CMD_INITIALIZE:
assert(sizeof(INIT_WEDIT) == Qty);
piwed = (INIT_WEDIT*)IStrm;
pem->style = piwed->style;
pem->nSpcRow = piwed->nSpcRow;
pem->nSpcClm = piwed->nSpcClm;
pem->text = piwed->text;
pem->cpty = piwed->cpty;
pem->clen = piwed->clen;
pem->format = piwed->format;
pem->font = piwed->font;
pem->crsel = piwed->crsel;
pem->crnor = piwed->crnor;
pem->crbgsel = piwed->crbgsel;
pem->hBmpLRIntArea = piwed->hBmpLRIntArea;
pem->nHSBHeight = piwed->nHSBHeight;
pem->nVSBWidth = piwed->nVSBWidth;
pem->GetBitmapsForHScrollBar = piwed->GetBitmapsForHScrollBar;
pem->GetBitmapsForVScrollBar = piwed->GetBitmapsForVScrollBar;
return IR_P;
case SET_WGI_WINDOWPOS:
VO_Interact2(pem->pWGrinterface, SET_WGI_WINDOWPOS, IStrm, sizeof(WINPOSINFO), &caller);
Paint(This, NULL, &caller);
return IR_P;
case SET_WGI_TIRECT:
assert(Qty >= sizeof(RECT));
pem_wgr->ti.rect = *(RECT*)IStrm;
Paint(This, NULL, &caller);
return IR_P;
case SET_WGI_TEXT:
assert(Qty < (BYTKTY)pem_wgr->ti.cpty);
wcscpy(pem_wgr->ti.text, (TCHAR*)IStrm);
pem_wgr->ti.clen = Qty;
Paint(This, NULL, &caller);
return IR_P;
case MSG_WGI_FOCUSOVERMOVE:
assert(sizeof(POINT) == Qty);
if(pem->pHScrBar != NULL)
{
pem_parwdl = (EM_WDIALOG*)GetEMofBN(pem_wgr->pParentWnd, MSN_WDIALOG);
pem_sbwgr = (EM_WGRINTERFACE*)GetEMofBN(pem->pHScrBar, MSN_WGRINTERFACE);
if(PtInRect(&pem_sbwgr->rect, *(POINT*)IStrm))
{
pem_parwdl->ctrls.icwf = pem_sbwgr->no;
VO_Interact2(pem->pHScrBar, MSG_WGI_FOCUSOVERMOVE, IStrm, sizeof(POINT), &caller);
return IR_P;
}
}
if(pem->pVScrBar != NULL)
{
pem_parwdl = (EM_WDIALOG*)GetEMofBN(pem_wgr->pParentWnd, MSN_WDIALOG);
pem_sbwgr = (EM_WGRINTERFACE*)GetEMofBN(pem->pVScrBar, MSN_WGRINTERFACE);
if(PtInRect(&pem_sbwgr->rect, *(POINT*)IStrm))
{
pem_parwdl->ctrls.icwf = pem_sbwgr->no;
VO_Interact2(pem->pVScrBar, MSG_WGI_FOCUSOVERMOVE, IStrm, sizeof(POINT), &caller);
return IR_P;
}
}
return IR_P;
case MSG_WGI_FOCUSBT1DOWN:
assert(sizeof(POINT) == Qty);
if(!pem->bFocus)
{
pem_parwgr = (EM_WGRINTERFACE*)GetEMofBN(pem_wgr->pParentWnd, MSN_WGRINTERFACE);
pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
CreateCaret(pem_parwpa->hWnd, NULL, pem->CaretWidth, pem->CharHeight);
pem->bFocus = TRUE;
}
SetCaretPosByPoint(This, *(POINT*)IStrm);
return IR_P;
case MSG_WGI_FOCUSLOSE:
assert(sizeof(POINT) == Qty);
if(!PtInRect(&pem_wgr->rect, *(POINT*)IStrm))
{
DestroyCaret();
pem->bFocus = FALSE;
pem->bCaretVisible = FALSE;
}
return IR_P;
case MSG_WGI_KEYDOWN:
assert(sizeof(int) <= Qty);
pem_parwgr = (EM_WGRINTERFACE*)GetEMofBN(pem_wgr->pParentWnd, MSN_WGRINTERFACE);
pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
switch (*(int*)IStrm)
{
case VK_RIGHT: // right arrow
MoveCaretToNextCharacter(This);
break;
case VK_LEFT: // left arrow
MoveCaretToPrevCharacter(This);
break;
case VK_HOME:
MoveCaretToRowBeginning(This);
return IR_P;
case VK_END:
MoveCaretToRowEnd(This);
return IR_P;
case VK_UP:
MoveCaretToPrevRow(This);
break;
case VK_DOWN:
MoveCaretToNextRow(This);
break;
case VK_DELETE:
if(pem->nCaretChar == pem->clen)
{
ShowCaret(pem_parwpa->hWnd);
return IR_N;
}
Delete(This, pem->nCaretChar, pem->nCaretChar, &caller);
break;
default:
return IR_P;
}
return IR_P;
case MSG_WGI_CHAR:
assert(sizeof(TCHAR) <= Qty);
pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
switch (*(TCHAR*)IStrm)
{
case 0x08: // backspace
if(0 == pem->nCaretChar)
{
ShowCaret(pem_parwpa->hWnd);
return IR_N;
}
Delete(This, pem->nCaretChar-1, pem->nCaretChar-1, &caller);
break;
default: // displayable character
if(pem->clen == pem->cpty)
{
ShowCaret(pem_parwpa->hWnd);
return IR_N;
}
memmove(pem->text + pem->nCaretChar + 1, pem->text + pem->nCaretChar, (pem->clen - pem->nCaretChar) * sizeof(TCHAR));
if(0x0D == *(TCHAR*)IStrm) // "Enter" key ?
{
if(pem->style & ES_SINGLELINE)
return IR_P;
pem->text[pem->nCaretChar] = 0x0A;
}else
{
pem->text[pem->nCaretChar] = *(TCHAR*)IStrm;
}
pem->clen++;
CalculateText(This, &caller);
MoveCaretToNextCharacter(This);
Paint(This, NULL, &caller);
break;
}
return IR_P;
case SET_WGI_FONT:
assert(sizeof(HFONT) == Qty);
pem->font = *(HFONT*)IStrm;
pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
hdc = GetDC(pem_parwpa->hWnd);
if(pem->font)
hOldFont = SelectObject(hdc, pem->font);
// Get the metrics of the current font.
GetTextMetrics(hdc, &tm);
if(pem->font)
SelectObject(hdc, hOldFont);
ReleaseDC(pem_parwpa->hWnd, hdc);
pem->CharHeight = tm.tmHeight;
WriteText(This, &caller);
return IR_P;
default:
break;
}
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_INTERACT2;
}
/**
*
* 名称:WEdit_Interact3
*/
static IRESULT WEdit_Interact3(OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
SI32 delta;
VR caller;
float fSCtoEnd;
long n;
caller.cr = pCaller->cr;
caller.mr = This->OID;
switch(Act)
{
case CMD_WGI_HFROLL3:
case CMD_WGI_HBROLL3:
assert(sizeof(SI32) == Qty);
assert(sizeof(float) == Cty);
delta = *(SI32*)IStrm;
if(CMD_WGI_HFROLL3 == Act)
{
n = pem_wgr->rcfi.right - pem_wgr->rcfi.left;
pem->xDelta -= delta;
if(n - pem->xDelta > pem->CttWidth)
pem->xDelta = n - pem->CttWidth;
fSCtoEnd = (float) (pem->CttWidth + pem->xDelta - n) / pem->CttWidth;
}else
{
n = pem_wgr->rcfi.right - pem_wgr->rcfi.left;
pem->xDelta += delta;
if(pem->xDelta > 0)
pem->xDelta = 0;
fSCtoEnd = (float) (-pem->xDelta) / pem->CttWidth;
}
Paint(This, NULL, &caller);
*(float*)OStrm = fSCtoEnd;
*pQty = sizeof(float);
return IR_P;
case CMD_WGI_VFROLL3:
case CMD_WGI_VBROLL3:
assert(sizeof(SI32) == Qty);
assert(sizeof(float) == Cty);
delta = *(SI32*)IStrm;
if(CMD_WGI_VFROLL3 == Act)
{
n = pem_wgr->rcfi.bottom - pem_wgr->rcfi.top;
pem->yDelta -= delta;
if(n - pem->yDelta > pem->CttHeight)
pem->yDelta = n - pem->CttHeight;
fSCtoEnd = (float) (pem->CttHeight + pem->yDelta - n) / pem->CttHeight;
}else
{
n = pem_wgr->rcfi.bottom - pem_wgr->rcfi.bottom;
pem->yDelta += delta;
if(pem->yDelta > 0)
pem->yDelta = 0;
fSCtoEnd = (float) (-pem->yDelta) / pem->CttHeight;
}
Paint(This, NULL, &caller);
*(float*)OStrm = fSCtoEnd;
*pQty = sizeof(float);
return IR_P;
default:
break;
}
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_INTERACT3;
}
/**
*
* 名称:WEdit_Close
*/
static IRESULT WEdit_Close(OBJECT* This, const VR* pCaller)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
OBS_OBJECT_CLOSE_;
/* 在下面完成接口自己的任务。*/
if(0 == This->RefCnt)
{
if(pem->pAPWC)
free(pem->pAPWC);
return IR_P_RCZERO;
}
return IR_P;
}
/*========================+ TOG +========================*/
/**
*
* 名称:TOG_WEdit
*/
VOID TOG_WEdit(OBJECT* pObj)
{
pObj->Open = WEdit_Open;
pObj->Input = WEdit_Input;
pObj->Output = WEdit_Output;
pObj->IOput = WEdit_IOput;
pObj->Interact0 = WEdit_Interact0;
pObj->Interact1 = WEdit_Interact1;
pObj->Interact2 = WEdit_Interact2;
pObj->Interact3 = WEdit_Interact3;
pObj->Close = WEdit_Close;
}
/*=======================+ IRF(s) +======================*/
/* ... */
/*====================+ Function(s) +====================*/
/**
*
* NAME: CreateHScrollBar
* DESC: Create horizontal scroll bar.
*/
static BOOL CreateHScrollBar(OBJECT* This, int length, SI32 scrlen, const VR* pCaller)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WGRINTERFACE* pem_parwgr;
EM_WDIALOG* pem_parwdl;
INIT_WGRINTERFACE iwgr;
INIT_WSCROLLBAR iwsb;
SCROLLBARBITMAPS sbbmps;
CONTROL** ppACtrl;
OBJECT* pObject;
int x, y;
assert(NULL == pem->pHScrBar);
if(pem->nHSBHeight > pem_wgr->rcfi.bottom - pem_wgr->rcfi.top)
pem->nHSBHeight = pem_wgr->rcfi.bottom - pem_wgr->rcfi.top;
pem_parwgr = (EM_WGRINTERFACE*)GetEMofBN(pem_wgr->pParentWnd, MSN_WGRINTERFACE);
pem_parwdl = (EM_WDIALOG*)GetEMofBN(pem_wgr->pParentWnd, MSN_WDIALOG);
memset(&iwgr, 0, sizeof(INIT_WGRINTERFACE));
memset(&iwsb, 0, sizeof(INIT_WSCROLLBAR));
CreateObject(MSN_WSCROLLBAR, 0, 0, 1, &pem->pHScrBar);
VO_Open(pem->pHScrBar, pCaller);
x = pem_wgr->rect.left + pem_wgr->rcfi.left;
y = pem_wgr->rect.top + pem_wgr->rcfi.bottom - pem->nHSBHeight;
pem->GetBitmapsForHScrollBar(pem_wgr->pParentWnd, &sbbmps);
iwsb.pOwner = This;
iwsb.scrlen = scrlen;
iwsb.hBmpBase = sbbmps.hBmpBase;
iwsb.hBmpBRBNormal = sbbmps.hBmpBRBNormal;
iwsb.hBmpBRBOver = sbbmps.hBmpBRBOver;
iwsb.hBmpBRBDown = sbbmps.hBmpBRBDown;
iwsb.hBmpFRBNormal = sbbmps.hBmpFRBNormal;
iwsb.hBmpFRBOver = sbbmps.hBmpFRBOver;
iwsb.hBmpFRBDown = sbbmps.hBmpFRBDown;
iwsb.hBmpRBNormal = sbbmps.hBmpRBNormal;
iwsb.hBmpRBOver = sbbmps.hBmpRBOver;
iwsb.hBmpRBDown = sbbmps.hBmpRBDown;
iwgr.hInstance = pem_wgr->hInstance;
iwgr.pParentWnd = pem_wgr->pParentWnd;
iwgr.no = pem_wgr->no - 2;
iwgr.rect.left = x;
iwgr.rect.right = x + length;
iwgr.rect.top = y;
iwgr.rect.bottom = y + pem->nHSBHeight;
iwgr.rcfi.left = 1;
iwgr.rcfi.top = 1;
iwgr.rcfi.right = length - 1;
iwgr.rcfi.bottom = pem->nHSBHeight - 1;
ppACtrl = &pem_parwdl->ctrls.pACtrl;
(*ppACtrl)[pem_wgr->no-2].pCtrl = pem->pHScrBar;
(*ppACtrl)[pem_wgr->no-2].rect.left = pem_parwgr->rcfi.left + iwgr.rect.left;
(*ppACtrl)[pem_wgr->no-2].rect.top = pem_parwgr->rcfi.top + iwgr.rect.top;
(*ppACtrl)[pem_wgr->no-2].rect.right = pem_parwgr->rcfi.left + iwgr.rect.right;
(*ppACtrl)[pem_wgr->no-2].rect.bottom = pem_parwgr->rcfi.top + iwgr.rect.bottom;
pObject = GetBN(pem->pHScrBar, MSN_WGRINTERFACE);
VO_Interact2(pObject, CMD_INITIALIZE, (BYTE*)&iwgr, sizeof(INIT_WGRINTERFACE), pCaller);
VO_Interact2(pem->pHScrBar, CMD_INITIALIZE, (BYTE*)&iwsb, sizeof(INIT_WSCROLLBAR), pCaller);
VO_Interact0(pem->pHScrBar, CMD_PREPARE, pCaller);
pem_wgr->rcfi.bottom -= pem->nHSBHeight;
return TRUE;
}
/**
*
* NAME: CreateVScrollBar
* DESC: Create vertical scroll bar.
*/
static BOOL CreateVScrollBar(OBJECT* This, int length, SI32 scrlen, const VR* pCaller)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WGRINTERFACE* pem_parwgr;
EM_WDIALOG* pem_parwdl;
INIT_WGRINTERFACE iwgr;
INIT_WSCROLLBAR iwsb;
SCROLLBARBITMAPS sbbmps;
CONTROL** ppACtrl;
OBJECT* pObject;
int x, y;
assert(NULL == pem->pVScrBar);
if(pem->nVSBWidth > pem_wgr->rcfi.right - pem_wgr->rcfi.left)
pem->nVSBWidth = pem_wgr->rcfi.right - pem_wgr->rcfi.left;
pem_parwgr = (EM_WGRINTERFACE*)GetEMofBN(pem_wgr->pParentWnd, MSN_WGRINTERFACE);
pem_parwdl = (EM_WDIALOG*)GetEMofBN(pem_wgr->pParentWnd, MSN_WDIALOG);
memset(&iwgr, 0, sizeof(INIT_WGRINTERFACE));
memset(&iwsb, 0, sizeof(INIT_WSCROLLBAR));
CreateObject(MSN_WSCROLLBAR, 0, 0, 1, &pem->pVScrBar);
VO_Open(pem->pVScrBar, pCaller);
x = pem_wgr->rect.left + pem_wgr->rcfi.right - pem->nVSBWidth;
y = pem_wgr->rect.top + pem_wgr->rcfi.top;
pem->GetBitmapsForVScrollBar(pem_wgr->pParentWnd, &sbbmps);
iwsb.pOwner = This;
iwsb.scrlen = scrlen;
iwsb.hBmpBase = sbbmps.hBmpBase;
iwsb.hBmpBRBNormal = sbbmps.hBmpBRBNormal;
iwsb.hBmpBRBOver = sbbmps.hBmpBRBOver;
iwsb.hBmpBRBDown = sbbmps.hBmpBRBDown;
iwsb.hBmpFRBNormal = sbbmps.hBmpFRBNormal;
iwsb.hBmpFRBOver = sbbmps.hBmpFRBOver;
iwsb.hBmpFRBDown = sbbmps.hBmpFRBDown;
iwsb.hBmpRBNormal = sbbmps.hBmpRBNormal;
iwsb.hBmpRBOver = sbbmps.hBmpRBOver;
iwsb.hBmpRBDown = sbbmps.hBmpRBDown;
iwgr.hInstance = pem_wgr->hInstance;
iwgr.pParentWnd = pem_wgr->pParentWnd;
iwgr.no = pem_wgr->no - 1;
iwgr.rect.left = x;
iwgr.rect.right = x + pem->nVSBWidth;
iwgr.rect.top = y;
iwgr.rect.bottom = y + length;
iwgr.rcfi.left = 1;
iwgr.rcfi.top = 1;
iwgr.rcfi.right = pem->nVSBWidth - 1;
iwgr.rcfi.bottom = length - 1;
ppACtrl = &pem_parwdl->ctrls.pACtrl;
(*ppACtrl)[pem_wgr->no-1].pCtrl = pem->pVScrBar;
(*ppACtrl)[pem_wgr->no-1].rect.left = pem_parwgr->rcfi.left + iwgr.rect.left;
(*ppACtrl)[pem_wgr->no-1].rect.top = pem_parwgr->rcfi.top + iwgr.rect.top;
(*ppACtrl)[pem_wgr->no-1].rect.right = pem_parwgr->rcfi.left + iwgr.rect.right;
(*ppACtrl)[pem_wgr->no-1].rect.bottom = pem_parwgr->rcfi.top + iwgr.rect.bottom;
pObject = GetBN(pem->pVScrBar, MSN_WGRINTERFACE);
VO_Interact2(pObject, CMD_INITIALIZE, (BYTE*)&iwgr, sizeof(INIT_WGRINTERFACE), pCaller);
VO_Interact2(pem->pVScrBar, CMD_INITIALIZE, (BYTE*)&iwsb, sizeof(INIT_WSCROLLBAR), pCaller);
VO_Interact0(pem->pVScrBar, CMD_PREPARE, pCaller);
pem_wgr->rcfi.right -= pem->nVSBWidth;
return TRUE;
}
/**
*
* NAME: DestroyScrollBar
*/
static BOOL DestroyScrollBar(OBJECT* This, const VR* pCaller)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WDIALOG* pem_parwdl;
CONTROL** ppACtrl;
assert(pem->pHScrBar != NULL || pem->pVScrBar != NULL);
pem_parwdl = (EM_WDIALOG*)GetEMofBN(pem_wgr->pParentWnd, MSN_WDIALOG);
ppACtrl = &pem_parwdl->ctrls.pACtrl;
if(pem->pHScrBar != NULL)
{
VO_Close(pem->pHScrBar, pCaller);
DestroyObject(pem->pHScrBar);
(*ppACtrl)[pem_wgr->no-2].pCtrl = NULL;
pem_wgr->rcfi.bottom += pem->nHSBHeight;
}
if(pem->pVScrBar != NULL)
{
VO_Close(pem->pVScrBar, pCaller);
DestroyObject(pem->pVScrBar);
(*ppACtrl)[pem_wgr->no-1].pCtrl = NULL;
pem_wgr->rcfi.right += pem->nVSBWidth;
}
pem_parwdl->ctrls.iccf = -1;
pem_parwdl->ctrls.ichf = pem_wgr->no;
pem_parwdl->ctrls.icwf = pem_wgr->no;
return TRUE;
}
/**
*
* 名称:CalculateText
*/
static void CalculateText(OBJECT* This, const VR* pCaller)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WPANEL* pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
HFONT hOldFont;
HDC hdc;
SIZE size;
BOOL bCVSB, bCHSB;
long rcfiLeft, rcfiRight, rcfiTop, rcfiBottom;
SI32 cttw;
long i, n, m;
if(!(pem->style & ES_HSCROLLBAR) && (pem->pHScrBar != NULL))
DestroyScrollBar(This, pCaller);
else if(!(pem->style & ES_VSCROLLBAR) && (pem->pVScrBar != NULL))
DestroyScrollBar(This, pCaller);
hdc = GetDC(pem_parwpa->hWnd);
if(pem->font)
hOldFont = SelectObject(hdc, pem->font);
bCVSB = bCHSB = FALSE;
rcfiLeft = pem_wgr->rcfi.left;
rcfiRight = (pem->pVScrBar != NULL) ? pem_wgr->rcfi.right + pem->nVSBWidth : pem_wgr->rcfi.right;
rcfiTop = pem_wgr->rcfi.top;
rcfiBottom = (pem->pHScrBar != NULL) ? pem_wgr->rcfi.bottom + pem->nHSBHeight : pem_wgr->rcfi.bottom;
pem->NumRow = 1;
n = m = 0;
pem->CttWidth = cttw = 0;
for(i=0; i<pem->clen; i++)
{
if(pem->style & ES_SINGLELINE)
{
GetTextExtentPoint32(hdc, pem->text+i, 1, &size);
pem->pAPWC[i].x = n;
pem->pAPWC[i].y = 0;
pem->CttWidth = n + size.cx;
n += size.cx + pem->nSpcClm;
}else
{
if(0x0A == pem->text[i])
{
pem->pAPWC[i].x = n;
pem->pAPWC[i].y = m;
n = 0;
m += pem->CharHeight + pem->nSpcRow;
pem->NumRow++;
if(cttw > pem->CttWidth)
pem->CttWidth = cttw;
cttw = 0;
}else
{
GetTextExtentPoint32(hdc, pem->text+i, 1, &size);
if(!(pem->style & ES_UNAUTOLINEFEED))
{
if(rcfiLeft + n + size.cx > rcfiRight)
{
n = 0;
m += pem->CharHeight + pem->nSpcRow;
pem->NumRow++;
cttw = 0;
}
}
pem->pAPWC[i].x = n;
pem->pAPWC[i].y = m;
cttw = n + size.cx;
if(cttw > pem->CttWidth)
pem->CttWidth = cttw;
n += size.cx + pem->nSpcClm;
}
}
}
pem->CttHeight = pem->NumRow * (pem->CharHeight + pem->nSpcRow) - pem->nSpcRow;
if(pem->font)
SelectObject(hdc, hOldFont);
ReleaseDC(pem_parwpa->hWnd, hdc);
if(pem->pHScrBar != NULL)
{
if(pem->pVScrBar != NULL)
{
if(pem->CttWidth <= rcfiRight - rcfiLeft - pem->nVSBWidth
|| pem->CttHeight <= rcfiBottom - rcfiTop - pem->nHSBHeight)
DestroyScrollBar(This, pCaller);
}else
{
if(pem->CttWidth <= rcfiRight - rcfiLeft)
DestroyScrollBar(This, pCaller);
}
}else if(pem->pVScrBar != NULL)
{
if(pem->CttHeight <= rcfiBottom - rcfiTop)
DestroyScrollBar(This, pCaller);
}
if((pem->style & ES_HSCROLLBAR) && (NULL == pem->pHScrBar))
{
n = (pem->pVScrBar != NULL) ? pem->nVSBWidth : 0;
if(pem->CttWidth > rcfiRight - rcfiLeft - n)
bCHSB = TRUE;
}
if((pem->style & ES_VSCROLLBAR) && (NULL == pem->pVScrBar))
{
n = (pem->pHScrBar != NULL) ? pem->nHSBHeight : 0;
if(pem->CttHeight > rcfiBottom - rcfiTop - n)
bCVSB = TRUE;
}
if(TRUE == bCHSB)
{
if(pem->pVScrBar != NULL)
{
DestroyScrollBar(This, pCaller);
CreateVScrollBar(This, pem_wgr->rcfi.bottom - pem_wgr->rcfi.top - pem->nHSBHeight, pem->CttHeight, pCaller);
n = pem_wgr->rcfi.right - pem_wgr->rcfi.left;
}else if(TRUE == bCVSB)
{
n = pem_wgr->rcfi.right - pem_wgr->rcfi.left - pem->nVSBWidth;
}else
{
n = pem_wgr->rcfi.right - pem_wgr->rcfi.left;
}
CreateHScrollBar(This, n, pem->CttWidth, pCaller);
}else if(pem->pHScrBar != NULL && pem->lastCttWidth != pem->CttWidth)
{
VO_Interact2(pem->pHScrBar, MSG_WGI_SCRLENCHANGED, (BYTE*)&pem->CttWidth, sizeof(UI32), pCaller);
}
if(TRUE == bCVSB)
{
if(pem->pHScrBar != NULL)
{
DestroyScrollBar(This, pCaller);
CreateHScrollBar(This, pem_wgr->rcfi.right - pem_wgr->rcfi.left - pem->nVSBWidth, pem->CttWidth, pCaller);
}
CreateVScrollBar(This, pem_wgr->rcfi.bottom - pem_wgr->rcfi.top, pem->CttHeight, pCaller);
}else if(pem->pVScrBar != NULL && pem->lastCttHeight != pem->CttHeight)
{
VO_Interact2(pem->pVScrBar, MSG_WGI_SCRLENCHANGED, (BYTE*)&pem->CttHeight, sizeof(UI32), pCaller);
}
pem->lastCttWidth = pem->CttWidth;
pem->lastCttHeight = pem->CttHeight;
return;
}
/**
*
* 名称:MakeCaretVisible
*/
static void MakeCaretVisible(OBJECT* This)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WPANEL* pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
if(pem->bCaretVisible)
return;
ShowCaret(pem_parwpa->hWnd);
pem->bCaretVisible = TRUE;
return;
}
/**
*
* 名称:MakeCaretInvisible
*/
static void MakeCaretInvisible(OBJECT* This)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WPANEL* pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
if(!pem->bCaretVisible)
return;
HideCaret(pem_parwpa->hWnd);
pem->bCaretVisible = FALSE;
return;
}
/**
*
* 名称:SetCaretPosByPoint
*/
static void SetCaretPosByPoint(OBJECT* This, POINT pt)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WGRINTERFACE* pem_parwgr = (EM_WGRINTERFACE*)GetEMofBN(pem_wgr->pParentWnd, MSN_WGRINTERFACE);
EM_WPANEL* pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
SIZE oldSize, newSize;
HFONT hOldFont;
HDC hdc;
RECT rc;
int i;
if(pem->clen > 0)
{
hdc = GetDC(pem_parwpa->hWnd);
if(pem->font)
hOldFont = SelectObject(hdc, pem->font);
pt.x -= pem_wgr->rect.left + pem_wgr->rcfi.left;
pt.y -= pem_wgr->rect.top + pem_wgr->rcfi.top;
i=0;
pem->nCaretRow = 0;
while(1)
{
if(pem->text[i] != 0x0A)
{
GetTextExtentPoint32(hdc, pem->text+i, 1, &newSize);
if(0 == i)
{
pem->nCaretRow = 1;
pem->nCaretClm = 1;
rc.left = rc.top = 0;
rc.right = newSize.cx / 2;
rc.bottom = newSize.cy + pem->nSpcRow / 2;
}else
{
if(pem->pAPWC[i].y > pem->pAPWC[i-1].y)
{
pem->nCaretRow++;
pem->nCaretClm = 1;
rc.left = rc.right;
rc.right = pem_wgr->rcfi.right-pem_wgr->rcfi.left;
if(PtInRect(&rc, pt))
break;
rc.left = 0;
rc.right = newSize.cx / 2;
rc.top = rc.bottom;
rc.bottom += pem->nSpcRow + newSize.cy;
}else
{
pem->nCaretClm++;
rc.left = rc.right;
rc.right += pem->nSpcClm + (oldSize.cx + newSize.cx) / 2;
}
}
if(PtInRect(&rc, pt))
break;
oldSize = newSize;
}else
{
pem->nCaretRow++;
pem->nCaretClm = 0;
}
if(++i == pem->clen)
break;
}
pem->nCaretChar = i;
if(pem->font)
SelectObject(hdc, hOldFont);
ReleaseDC(pem_parwpa->hWnd, hdc);
}else
{
pem->nCaretChar = 0;
pem->nCaretRow = 1;
pem->nCaretClm = 0;
}
SetCaretPosBYnCaretChar(This, SET_CARETPOS_BY_POINT);
}
/**
*
* 名称:SetCaretPosBYnCaretChar
*/
static void SetCaretPosBYnCaretChar(OBJECT* This, const UI32 flag)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WGRINTERFACE* pem_parwgr = (EM_WGRINTERFACE*)GetEMofBN(pem_wgr->pParentWnd, MSN_WGRINTERFACE);
EM_WPANEL* pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
HFONT hOldFont;
HDC hdc;
SIZE size;
int i, x, y;
if(pem->nCaretChar > 0)
{
i = pem->nCaretChar-1;
do{
if(pem->nCaretChar < pem->clen)
{
if((pem->pAPWC[pem->nCaretChar].y > pem->pAPWC[i].y) && (pem->text[pem->nCaretChar] != 0x0A))
{
if(!(flag & MOVE_CARET_TO_ROWEND)
&& !(flag & MOVE_CARET_TO_PREVROW)
&& !(flag & MOVE_CARET_TO_NEXTROW)
|| (flag & MOVE_CARET_TO_PREVROW && 0 == pem->nCaretClm)
|| (flag & MOVE_CARET_TO_NEXTROW && 0 == pem->nCaretClm))
{
pem->CaretX = 0;
pem->CaretY = pem->pAPWC[pem->nCaretChar].y;
break;
}
}
}
if(0x0A == pem->text[i])
{
pem->CaretX = 0;
pem->CaretY = pem->pAPWC[i].y + pem->CharHeight + pem->nSpcRow;
}else
{
pem->CaretX = pem->pAPWC[i].x;
hdc = GetDC(pem_parwpa->hWnd);
if(pem->font)
hOldFont = SelectObject(hdc, pem->font);
GetTextExtentPoint32(hdc, pem->text+i, 1, &size);
if(pem->font)
SelectObject(hdc, hOldFont);
ReleaseDC(pem_parwpa->hWnd, hdc);
pem->CaretX += size.cx;
pem->CaretY = pem->pAPWC[i].y;
}
break;
}while(1);
}else if(0 == pem->clen)
{
pem->CaretX = 0;
pem->CaretY = 0;
}else
{
pem->CaretX = pem->pAPWC[0].x;
pem->CaretY = pem->pAPWC[0].y;
}
x = pem->CaretX + pem_parwgr->rcfi.left + pem_wgr->rect.left + pem_wgr->rcfi.left;
y = pem->CaretY + pem_parwgr->rcfi.top + pem_wgr->rect.top + pem_wgr->rcfi.top;
SetCaretPos(x, y);
if(pem->CaretX >= 0 && pem->CaretX <= pem_wgr->rcfi.right && pem->CaretY >= 0 && pem->CaretY <= pem_wgr->rcfi.bottom)
MakeCaretVisible(This);
return;
}
/**
*
* 名称:MoveCaretToPrevCharacter
*/
static void MoveCaretToPrevCharacter(OBJECT* This)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
int i, j;
if(0 == pem->nCaretChar)
return;
i = pem->nCaretChar - 1;
if(i >= 0)
{
do{
if(pem->pAPWC[i].y < pem->CaretY)
{
pem->nCaretRow--;
for(j = i; j >= 0 ; j--)
{
if(pem->pAPWC[j].y < pem->pAPWC[i].y)
break;
}
pem->nCaretClm = j >= 0 ? i-j : i;
}else
{
pem->nCaretClm--;
}
break;
}while(0);
}else
{
pem->nCaretRow = 1;
pem->nCaretClm = 0;
}
pem->nCaretChar--;
SetCaretPosBYnCaretChar(This, MOVE_CARET_TO_PREVCHARACTER);
return;
}
/**
*
* 名称:MoveCaretToNextCharacter
*/
static void MoveCaretToNextCharacter(OBJECT* This)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
if(pem->nCaretChar == pem->clen)
return;
if(pem->pAPWC[pem->nCaretChar].y > pem->CaretY || 0x0A == pem->text[pem->nCaretChar])
{
pem->nCaretRow++;
pem->nCaretClm = pem->text[pem->nCaretChar] != 0x0A ? 1 : 0;
}else if((pem->nCaretChar+1 < pem->clen)
&& (pem->pAPWC[pem->nCaretChar+1].y > pem->CaretY && pem->text[pem->nCaretChar+1] != 0x0A))
{
pem->nCaretRow++;
pem->nCaretClm = 0;
}else
{
pem->nCaretClm++;
}
pem->nCaretChar++;
SetCaretPosBYnCaretChar(This, MOVE_CARET_TO_NEXTCHARACTER);
return;
}
/**
*
* 名称:MoveCaretToPrevRow
*/
static void MoveCaretToPrevRow(OBJECT* This)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
int i, j, n, m, y;
if(1 == pem->nCaretRow)
return;
y = pem->CaretY;
j = 0;
for(i = pem->nCaretChar-1; i >= 0; i--)
{
if(pem->pAPWC[i].y < y)
{
if(2 == ++j)
break;
y = pem->pAPWC[i].y;
}
}
i++;
n = i + pem->nCaretClm;
m = 0;
for(j=i; j < n ; j++)
{
if(0x0A == pem->text[j])
{
m++;
continue;
}
if(pem->pAPWC[j].y > y)
break;
}
j -= m;
if(0x0A == pem->text[i])
{
if(j > i)
pem->nCaretClm = j - i - 1;
else
pem->nCaretClm = j - i;
}else
{
pem->nCaretClm = j - i;
}
pem->nCaretChar = i + pem->nCaretClm;
pem->nCaretRow--;
SetCaretPosBYnCaretChar(This, MOVE_CARET_TO_PREVROW);
return;
}
/**
*
* 名称:MoveCaretToNextRow
*/
static void MoveCaretToNextRow(OBJECT* This)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
int i, j, n, y;
if(pem->nCaretRow == pem->NumRow)
return;
y = pem->CaretY;
for(i = pem->nCaretChar-1; i < pem->clen; i++)
{
if(pem->pAPWC[i].y > y)
{
y = pem->pAPWC[i].y;
break;
}
}
n = 0;
for(j=i; j < pem->clen ; j++)
{
if(0x0A == pem->text[j])
{
n++;
continue;
}
if(pem->pAPWC[j].y > y)
break;
}
j -= n;
if(j-i < pem->nCaretClm)
pem->nCaretClm = j-i;
pem->nCaretChar = i + pem->nCaretClm;
pem->nCaretRow++;
SetCaretPosBYnCaretChar(This, MOVE_CARET_TO_NEXTROW);
return;
}
/**
*
* 名称:MoveCaretToRowBeginning
*/
static void MoveCaretToRowBeginning(OBJECT* This)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WGRINTERFACE* pem_parwgr = (EM_WGRINTERFACE*)GetEMofBN(pem_wgr->pParentWnd, MSN_WGRINTERFACE);
int i;
pem->nCaretClm = 0;
pem->CaretX = 0;
if(pem->nCaretChar > 0)
{
for(i = pem->nCaretChar-1; i < pem->clen; i--)
{
if(pem->pAPWC[i].y < pem->CaretY)
break;
}
pem->nCaretChar = i+1;
}
SetCaretPosBYnCaretChar(This, MOVE_CARET_TO_ROWBEGINNING);
return;
}
/**
*
* 名称:MoveCaretToRowEnd
*/
static void MoveCaretToRowEnd(OBJECT* This)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
//EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
//EM_WGRINTERFACE* pem_parwgr = (EM_WGRINTERFACE*)GetEMofBN(pem_wgr->pParentWnd, MSN_WGRINTERFACE);
//EM_WPANEL* pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
int i, n;
if(pem->nCaretChar == pem->clen)
return;
for(i = pem->nCaretChar; i < pem->clen; i++)
{
if(pem->pAPWC[i].y > pem->CaretY || 0x0A == pem->text[i])
break;
}
n = pem->nCaretChar;
pem->nCaretChar = i;
pem->nCaretClm += pem->nCaretChar - n;
SetCaretPosBYnCaretChar(This, MOVE_CARET_TO_ROWEND);
return;
}
/**
*
* 名称:Delete
*/
static void Delete(OBJECT* This, int iFirst, int iLast, const VR* pCaller)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
int i, y;
pem->clen -= iLast-iFirst+1;
memmove(pem->text+iFirst, pem->text+iLast+1, pem->clen * sizeof(TCHAR));
CalculateText(This, pCaller);
if(pem->clen > 0)
{
pem->nCaretRow = 1;
pem->nCaretClm = 0;
pem->nCaretChar = iFirst;
y = pem->pAPWC[0].y;
for(i=0; i < iFirst; i++)
{
if(0x0A == pem->text[i])
{
pem->nCaretRow++;
pem->nCaretClm = 0;
if(i < iFirst-1)
y = pem->pAPWC[i+1].y;
continue;
}
if(pem->pAPWC[i].y > y)
{
pem->nCaretRow++;
pem->nCaretClm = 0;
y = pem->pAPWC[i].y;
continue;
}
pem->nCaretClm++;
}
}else
{
pem->nCaretRow = 1;
pem->nCaretClm = 0;
pem->nCaretChar = 0;
}
SetCaretPosBYnCaretChar(This, DELETE_CHARACTER);
Paint(This, NULL, pCaller);
return;
}
/**
*
* 名称:WriteText
*/
static void WriteText(OBJECT* This, const VR* pCaller)
{
CalculateText(This, pCaller);
Paint(This, NULL, pCaller);
return;
}
/**
*
* 名称:Prepaint
* 描述:hBitmap - the bitmap to paint on the control. If NULL, paints the hBmpCurrent.
*/
static void Prepaint(OBJECT* This, HBITMAP hBitmap)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WGRINTERFACE* pem_parwgr = (EM_WGRINTERFACE*)GetEMofBN(pem_wgr->pParentWnd, MSN_WGRINTERFACE);
EM_WPANEL* pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
// EM_WDIALOG* pem_parwdl = (EM_WDIALOG*)GetEMofBN(pem_wgr->pParentWnd, MSN_WDIALOG);
EM_WGRINTERFACE* pem_sbwgr;
HBITMAP hNewBmp, hOldBmp1, hOldBmp2, hOldBmp3;
HDC hdc, memdc1, memdc2, memdc3;
HFONT hOldFont;
COLORREF crOldColor;
RECT rc;
BITMAP bm;
long i, n, m, w, h, x, y;
x = pem_parwgr->rcfi.left + pem_wgr->rect.left;
y = pem_parwgr->rcfi.top + pem_wgr->rect.top;
w = pem_wgr->rect.right - pem_wgr->rect.left;
h = pem_wgr->rect.bottom - pem_wgr->rect.top;
hdc = GetDC(pem_parwpa->hWnd);
memdc1 = CreateCompatibleDC(hdc);
memdc2 = CreateCompatibleDC(hdc);
hOldBmp1 = SelectObject(memdc1, pem_parwgr->hBmpCurrent);
if(!hBitmap)
hBitmap = pem_wgr->hBmpCurrent;
hOldBmp2 = SelectObject(memdc2, hBitmap);
GetObject(hBitmap, sizeof(bm), &bm);
//BitBlt(memdc1, x, y, w, h, memdc2, 0, 0, SRCCOPY);
StretchBlt(memdc1, x, y, w, h, memdc2, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
SetBkMode(memdc1, TRANSPARENT);
if(pem_wgr->ti.clen > 0)
{
if(pem_wgr->ti.font)
hOldFont = SelectObject(memdc1, pem_wgr->ti.font);
crOldColor = SetTextColor(memdc1, pem_wgr->ti.color);
rc = pem_wgr->ti.rect;
n = pem_parwgr->rcfi.left + pem_wgr->rect.left + pem_wgr->rcfi.left;
m = pem_parwgr->rcfi.top + pem_wgr->rect.top + pem_wgr->rcfi.top;
rc.left += n;
rc.top += m;
rc.right += n;
rc.bottom += m;
DrawText(memdc1, pem_wgr->ti.text, pem_wgr->ti.clen, &rc, pem_wgr->ti.format);
if(pem_wgr->ti.font)
SelectObject(memdc1, hOldFont);
SetTextColor(memdc1, crOldColor);
}
if(pem->clen > 0)
{
memdc3 = CreateCompatibleDC(hdc);
w = pem_wgr->rcfi.right - pem_wgr->rcfi.left;
h = pem_wgr->rcfi.bottom - pem_wgr->rcfi.top;
hNewBmp = CreateCompatibleBitmap(hdc, w, h);
hOldBmp3 = SelectObject(memdc3, hNewBmp);
BitBlt(memdc3, 0, 0, w, h, memdc2, pem_wgr->rcfi.left, pem_wgr->rcfi.top, SRCCOPY);
if(pem->font)
hOldFont = SelectObject(memdc3, pem->font);
crOldColor = SetTextColor(memdc3, pem->crnor);
SetBkMode(memdc3, TRANSPARENT);
for(i=0; i<pem->clen; i++)
{
if(0x0A == pem->text[i])
continue;
TextOut(memdc3, pem->pAPWC[i].x + pem->xDelta, pem->pAPWC[i].y + pem->yDelta, pem->text+i, 1);
}
if(pem->font)
SelectObject(memdc3, hOldFont);
SetTextColor(memdc3, crOldColor);
x = pem_parwgr->rcfi.left + pem_wgr->rect.left + pem_wgr->rcfi.left;
y = pem_parwgr->rcfi.top + pem_wgr->rect.top + pem_wgr->rcfi.top;
BitBlt(memdc1, x, y, w, h, memdc3, 0, 0, SRCCOPY);
SelectObject(memdc3, hOldBmp3);
DeleteDC(memdc3);
DeleteObject(hNewBmp);
}
if(pem->pHScrBar != NULL)
{
pem_sbwgr = (EM_WGRINTERFACE*)GetEMofBN(pem->pHScrBar, MSN_WGRINTERFACE);
SelectObject(memdc2, pem_sbwgr->hBmpCurrent);
x = pem_parwgr->rcfi.left + pem_wgr->rect.left + pem_wgr->rcfi.left;
y = pem_parwgr->rcfi.top + pem_wgr->rect.top + pem_wgr->rcfi.bottom;
w = pem_sbwgr->rect.right - pem_sbwgr->rect.left;
h = pem->nHSBHeight;
StretchBlt(memdc1, x, y, w, h, memdc2, 0, 0, w, h, SRCCOPY);
if(pem->pVScrBar != NULL)
{
GetObject(pem->hBmpLRIntArea, sizeof(bm), &bm);
SelectObject(memdc2, pem->hBmpLRIntArea);
StretchBlt(memdc1, x+w, y, pem->nVSBWidth, pem->nHSBHeight, memdc2, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
}
}
if(pem->pVScrBar != NULL)
{
pem_sbwgr = (EM_WGRINTERFACE*)GetEMofBN(pem->pVScrBar, MSN_WGRINTERFACE);
SelectObject(memdc2, pem_sbwgr->hBmpCurrent);
x = pem_parwgr->rcfi.left + pem_wgr->rect.left + pem_wgr->rcfi.right;
y = pem_parwgr->rcfi.top + pem_wgr->rect.top + pem_wgr->rcfi.top;
w = pem->nVSBWidth;
h = pem_sbwgr->rect.bottom - pem_sbwgr->rect.top;
StretchBlt(memdc1, x, y, w, h, memdc2, 0, 0, w, h, SRCCOPY);
}
SelectObject(memdc1, hOldBmp1);
DeleteDC(memdc1);
SelectObject(memdc2, hOldBmp2);
DeleteDC(memdc2);
ReleaseDC(pem_parwpa->hWnd, hdc);
return;
}
/**
*
* 名称:Paint
* 描述:hBitmap - the bitmap to paint on the control. If NULL, paints the hBmpCurrent.
*/
static void Paint(OBJECT* This, HBITMAP hBitmap, const VR* pCaller)
{
EM_WEDIT* pem = (EM_WEDIT*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WGRINTERFACE* pem_parwgr = (EM_WGRINTERFACE*)GetEMofBN(pem_wgr->pParentWnd, MSN_WGRINTERFACE);
EM_WPANEL* pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
// EM_WDIALOG* pem_parwdl = (EM_WDIALOG*)GetEMofBN(pem_wgr->pParentWnd, MSN_WDIALOG);
HDC hdc, memdc;
HBITMAP hOldBmp;
int w, h, x, y;
if(pem->bCaretVisible)
HideCaret(pem_parwpa->hWnd);
Prepaint(This, hBitmap);
x = pem_parwgr->rcfi.left + pem_wgr->rect.left;
y = pem_parwgr->rcfi.top + pem_wgr->rect.top;
w = pem_wgr->rect.right - pem_wgr->rect.left;
h = pem_wgr->rect.bottom - pem_wgr->rect.top;
hdc = GetDC(pem_parwpa->hWnd);
memdc = CreateCompatibleDC(hdc);
hOldBmp = SelectObject(memdc, pem_parwgr->hBmpCurrent);
BitBlt(hdc, x, y, w, h, memdc, x, y, SRCCOPY);
ReleaseDC(pem_parwpa->hWnd, hdc);
SelectObject(memdc, hOldBmp);
DeleteDC(memdc);
if(pem->bCaretVisible)
ShowCaret(pem_parwpa->hWnd);
return;
}