/**
*
* 文 件 名:WMenu.c
*
* 描 述:
*
* 创 建 者:赵平智 <[email protected]>
*
* 创建日期:20091116
*
* 备 注:
*
*
* * 维护历史 *
*
* <日期> <修改者>
* <修改内容...>
*
**/
#include "WMenu.h"
#include "../../../se/wgi.h"
#include "../WButton/WButton.h"
static const TCHAR gs_szWindowClass[] = TEXT("WMenu");
VOID TOG_WMenu(OBJECT* pObj);
static ATOM MyRegisterClass(HINSTANCE hInstance);
static LRESULT CALLBACK WMenuProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static int CalculateWidthOfText(HDC hdc, TCHAR* text, BYTKTY len);
static float RollAndCalculateScale2End(OBJECT* This, SI32 delta, int flag, const VR* pCaller);
/*=====================+ OICC label +====================*/
/*<oicc>*/
/*<ibn> WDialog </ibn>*/
/*<crt>*/
FRESULT CRT_WMenu(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_WDialog(OBJECT* pObj);
extern VOID TOG_WPanel(OBJECT* pObj);
extern VOID TOG_WGrinterface(OBJECT* pObj);
extern VOID TOG_OIOIC(OBJECT* pObj);
UI32 ux_ND = 5; /* ND数量。*/
UI32 ux_BN = 10; /* 各ND的BN数量之和。*/
UI32 ux_IB = 4; /* 各ND的IBN数量之和。*/
UI32 ux_CS = NumCR * 15; /* 各ND的最少CS数量之和。*/
UI32 ux_EM = sizeof(EM_WMENU) + sizeof(EM_WDIALOG) + sizeof(EM_WPANEL)
+ 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[4];
BYTE* p = pIC + sizeof(OBJECT) * ux_ND;
/*** 确定AND各元素 ***/
/** WMenu **/
pND = (OBJECT*)pIC;
TOG_WMenu(pND);
pND->MSN = MSN_WMENU;
pND->OID = (*pOID)++;
pND->po_AND = (OBJECT*)pIC;
pND->NND = ux_ND;
/** WDialog **/
TOG_WDialog(++pND);
pND->MSN = MSN_WDIALOG;
pND->OID = (*pOID)++;
pND->po_AND = (OBJECT*)pIC;
pND->NND = ux_ND;
/** WPanel **/
TOG_WPanel(++pND);
pND->MSN = MSN_WPANEL;
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 ***/
/** WMenu **/
pND = (OBJECT*)pIC;
/* - AIB - */
pND->ppo_AIB = (OBJECT**)p;
ArrMsn[0] = MSN_WDIALOG;
InitAIBofND(pND, ArrMsn, 1);
p += sizeof(OBJECT*) * 1;
/* - ABN - */
pND->ppo_ABN = (OBJECT**)p;
ArrMsn[0] = MSN_WDIALOG;
ArrMsn[1] = MSN_WPANEL;
ArrMsn[2] = MSN_WGRINTERFACE;
ArrMsn[3] = MSN_OIOIC;
InitABNofND(pND, ArrMsn, 4);
p += sizeof(OBJECT*) * 4;
/* - ACS - */
pND->pvr_ACS = (VR*)p;
pND->NCS = NumCR * 1;
p += sizeof(VR) * pND->NCS;
/* - EM - */
pND->pEM = (EM*)p;
p += sizeof(EM_WMENU);
/** WDialog **/
++pND;
/* - AIB - */
pND->ppo_AIB = (OBJECT**)p;
ArrMsn[0] = MSN_WPANEL;
InitAIBofND(pND, ArrMsn, 1);
p += sizeof(OBJECT*) * 1;
/* - ABN - */
pND->ppo_ABN = (OBJECT**)p;
ArrMsn[0] = MSN_WPANEL;
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 * 2;
p += sizeof(VR) * pND->NCS;
/* - EM - */
pND->pEM = (EM*)p;
p += sizeof(EM_WDIALOG);
/** WPanel **/
++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 * 3;
p += sizeof(VR) * pND->NCS;
/* - EM - */
pND->pEM = (EM*)p;
p += sizeof(EM_WPANEL);
/** 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 * 4;
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 * 5;
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 +=====================*/
/**
*
* 名称:WMenu_Open
*/
static IRESULT WMenu_Open(OBJECT* This, const VR* pCaller)
{
EM_WMENU* pem = (EM_WMENU*)This->pEM;
OBS_OBJECT_OPEN_;
/* 在下面完成接口自己的任务。*/
if(1 == This->RefCnt)
{
pem->pWGrinterface = GetBN(This, MSN_WGRINTERFACE);
pem->pWPanel = GetBN(This, MSN_WPANEL);
pem->pWDialog = GetBN(This, MSN_WDIALOG);
pem->pWndProc = WMenuProc;
}
return IR_P;
}
/**
*
* 名称:WMenu_Input
*/
static IRESULT WMenu_Input(OBJECT* This, BYTE* IStrm, BYTKTY Qty, const VR* pCaller)
{
/* ... */
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_INPUT;
}
/**
*
* 名称:WMenu_Output
*/
static IRESULT WMenu_Output(OBJECT* This, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
/* ... */
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_OUTPUT;
}
/**
*
* 名称:WMenu_IOput
*/
static IRESULT WMenu_IOput(OBJECT* This, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
/* ... */
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_IOPUT;
}
/**
*
* 名称:WMenu_Interact0
*/
static IRESULT WMenu_Interact0(OBJECT* This, ACTION Act, const VR* pCaller)
{
VR caller;
EM_WMENU* pem = (EM_WMENU*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WPANEL* pem_wpa = (EM_WPANEL*)pem->pWPanel->pEM;
EM_WDIALOG* pem_wdl = (EM_WDIALOG*)pem->pWDialog->pEM;
CONTROL** ppACtrl = &pem_wdl->ctrls.pACtrl;
CONTROL* pACtrl;
OBJECT* poWGrinterface;
EM_WPANEL* pem_parwpa;
INIT_WGRINTERFACE iwgr;
INIT_WBUTTON iwbt;
INIT_WSCROLLBAR iwsb;
SCROLLBARBITMAPS sbbmps;
WINPOSINFO wpi;
MENUITEM* pmit;
HDC hdc;
HFONT hOldFont;
SIZE size;
BITMAP bm;
SI32 delta;
SI32 maxWidth, maxHeight;
SI32 nHeightItem ;
SI32 nWidthMenu;
SI32 nHeightMenu;
int i, n;
caller.cr = pCaller->cr;
caller.mr = This->OID;
switch(Act)
{
case CMD_PREPARE:
if(0 == MyRegisterClass(pem_wgr->hInstance))
return IR_N;
return IR_P;
case CMD_WGI_POP:
pem_parwpa = (EM_WPANEL*)GetEMofBN(pem_wgr->pParentWnd, MSN_WPANEL);
pem_wpa->hWnd = CreateWindowEx(0, gs_szWindowClass, NULL, WS_POPUP | WS_VISIBLE,
pem_wgr->rect.left, pem_wgr->rect.top, 0, 0, pem_parwpa->hWnd, NULL, pem_wgr->hInstance, NULL);
SetWindowLong(pem_wpa->hWnd, GWL_USERDATA, (LONG)This);
hdc = GetDC(pem_wpa->hWnd);
if(pem_wgr->ti.font)
hOldFont = SelectObject(hdc, pem_wgr->ti.font);
n = maxWidth = maxHeight = 0;
pmit = pem->pfirstmit;
do
{
GetTextExtentPoint32(hdc, pmit->text, wcslen(pmit->text), &size);
if(size.cx > maxWidth)
maxWidth = size.cx;
if(size.cy > maxHeight)
maxHeight = size.cy;
n++;
pmit = pmit->next;
}while(pmit != NULL);
if(pem_wgr->ti.font)
SelectObject(hdc, hOldFont);
nHeightItem = (pem->style & MS_ITEMHEIGHTBMP) ? 0 : maxHeight;
nWidthMenu = (pem->style & MS_ITEMWIDTHSPS) ? pem_wgr->rect.right - pem_wgr->rect.left : maxWidth;
nHeightMenu = (pem->style & MS_ITEMHEIGHTBMP) ? 0 : n * nHeightItem;
*ppACtrl = (CONTROL*)calloc(n, sizeof(CONTROL));
if(NULL == *ppACtrl)
return IR_N;
// initialize Dialog
pem_wdl->ctrls.num = n;
memset(&iwgr, 0, sizeof(INIT_WGRINTERFACE));
memset(&iwbt, 0, sizeof(INIT_WBUTTON));
iwgr.hInstance = pem_wgr->hInstance;
iwgr.pParentWnd = This;
iwgr.ti.font = pem_wgr->ti.font;
iwgr.ti.color = pem_wgr->ti.color;
iwbt.crTextNormal = pem->crMITNormal;
iwbt.crTextOver = pem->crMITOver;
iwbt.crTextDown = pem->crMITDown;
iwbt.crTextDisable = pem->crMITDisable;
i = 0;
pmit = pem->pfirstmit;
do
{
CreateObject(MSN_WBUTTON, 0, 0, 1, &(*ppACtrl)[i].pCtrl);
VO_Open((*ppACtrl)[i].pCtrl, &caller);
pem->GetBitmapsForItem(pem_wgr->pParentWnd, pmit);
iwbt.hBmpOver = pmit->hBmpOver;
iwbt.hBmpNormal = pmit->hBmpNormal;
iwbt.hBmpDown = pmit->hBmpDown;
iwbt.hBmpDisable = pmit->hBmpDisable;
iwgr.hBmpCurrent = iwbt.hBmpNormal;
(*ppACtrl)[i].rect.left = 0;
(*ppACtrl)[i].rect.right = (*ppACtrl)[i].rect.left + nWidthMenu;
if(pem->style & MS_ITEMHEIGHTBMP)
{
GetObject(iwgr.hBmpCurrent, sizeof(bm), &bm);
(*ppACtrl)[i].rect.top += nHeightMenu;
(*ppACtrl)[i].rect.bottom = (*ppACtrl)[i].rect.top + bm.bmHeight;
nHeightMenu += bm.bmHeight;
}else
{
(*ppACtrl)[i].rect.top = i * nHeightItem;
(*ppACtrl)[i].rect.bottom = (*ppACtrl)[i].rect.top + nHeightItem;
}
iwgr.rect.left = (*ppACtrl)[i].rect.left;
iwgr.rect.top = (*ppACtrl)[i].rect.top;
iwgr.rect.right = (*ppACtrl)[i].rect.right;
iwgr.rect.bottom = (*ppACtrl)[i].rect.bottom;
iwgr.ti.text = pmit->text;
iwgr.ti.cpty = sizeof(pmit->text) / sizeof(TCHAR);
iwgr.ti.clen = wcslen(pmit->text);
iwgr.ti.format = TF_LEFT;
iwgr.ti.rect.left = iwgr.ti.rect.top = 0;
iwgr.ti.rect.right = nWidthMenu;
iwgr.ti.rect.bottom = nHeightItem;
poWGrinterface = GetBN((*ppACtrl)[i].pCtrl, MSN_WGRINTERFACE);
VO_Interact2(poWGrinterface, CMD_INITIALIZE, (BYTE*)&iwgr, sizeof(INIT_WGRINTERFACE), &caller);
VO_Interact2((*ppACtrl)[i].pCtrl, CMD_INITIALIZE, (BYTE*)&iwbt, sizeof(INIT_WBUTTON), &caller);
i++;
pmit = pmit->next;
}while(pmit != NULL);
if(!(pem->style & MS_AUTOHEIGHT))
{
if(nHeightMenu > pem_wgr->rect.bottom - pem_wgr->rect.top)
{
if(pem->style & MS_VSCROLLBAR)
{
n = i+1;
pACtrl = (CONTROL*)calloc(n, sizeof(CONTROL));
if(NULL == pACtrl)
return IR_N;
memcpy(pACtrl, pem_wdl->ctrls.pACtrl, sizeof(CONTROL) * pem_wdl->ctrls.num);
free(pem_wdl->ctrls.pACtrl);
pem_wdl->ctrls.pACtrl = pACtrl;
pem_wdl->ctrls.num = n;
pem->GetBitmapsForVScrollBar(pem_wgr->pParentWnd, &sbbmps);
GetObject(sbbmps.hBmpBRBNormal, sizeof(bm), &bm);
for(i = 0; i < n-1; i++)
{
(*ppACtrl)[i].rect.right -= bm.bmWidth + 2;
wpi.x = (*ppACtrl)[i].rect.left;
wpi.y = (*ppACtrl)[i].rect.top;
wpi.cx = (*ppACtrl)[i].rect.right - (*ppACtrl)[i].rect.left;
wpi.cy = (*ppACtrl)[i].rect.bottom - (*ppACtrl)[i].rect.top;
poWGrinterface = GetBN((*ppACtrl)[i].pCtrl, MSN_WGRINTERFACE);
VO_Interact2(poWGrinterface, SET_WGI_WINDOWPOS, (BYTE*)&wpi, sizeof(WINPOSINFO), &caller);
}
memset(&iwsb, 0, sizeof(INIT_WSCROLLBAR));
iwsb.pOwner = This;
iwsb.scrlen = nHeightMenu;
nHeightMenu = pem_wgr->rect.bottom - pem_wgr->rect.top;
// create Scroll Bar
CreateObject(MSN_WSCROLLBAR, 0, 0, 1, &(*ppACtrl)[i].pCtrl);
VO_Open((*ppACtrl)[i].pCtrl, &caller);
(*ppACtrl)[i].rect.right = pem_wgr->rect.right - pem_wgr->rect.left;
(*ppACtrl)[i].rect.bottom = pem_wgr->rect.bottom - pem_wgr->rect.top;
(*ppACtrl)[i].rect.left = (*ppACtrl)[i].rect.right - bm.bmWidth - 2;
(*ppACtrl)[i].rect.top = 0;
iwgr.rect.left = (*ppACtrl)[i].rect.left;
iwgr.rect.top = (*ppACtrl)[i].rect.top;
iwgr.rect.right = (*ppACtrl)[i].rect.right;
iwgr.rect.bottom = (*ppACtrl)[i].rect.bottom;
iwgr.rcfi.left = 1;
iwgr.rcfi.top = 1;
iwgr.rcfi.right = iwgr.rect.right - iwgr.rect.left - iwgr.rcfi.left;
iwgr.rcfi.bottom = iwgr.rect.bottom - iwgr.rect.top - iwgr.rcfi.top;
memset(&iwgr.ti, 0, sizeof(TEXTINFO));
poWGrinterface = GetBN((*ppACtrl)[i].pCtrl, MSN_WGRINTERFACE);
VO_Interact2(poWGrinterface, CMD_INITIALIZE, (BYTE*)&iwgr, sizeof(INIT_WGRINTERFACE), &caller);
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;
VO_Interact2((*ppACtrl)[i].pCtrl, CMD_INITIALIZE, (BYTE*)&iwsb, sizeof(INIT_WSCROLLBAR), &caller);
VO_Interact0((*ppACtrl)[i].pCtrl, CMD_PREPARE, &caller);
pem->nScrCtrl = 1;
}
}
}
ReleaseDC(pem_wpa->hWnd, hdc);
if(MS_UPDOWN & pem->style && MS_UPPOP & pem->style)
pem_wgr->rect.top -= nHeightMenu;
pem_wgr->rect.right = pem_wgr->rect.left + nWidthMenu;
pem_wgr->rect.bottom = pem_wgr->rect.top + nHeightMenu;
SendMessage(pem_wpa->hWnd, WM_INITDIALOG, 0, 0);
// ShowWindow(pem_wpa->hWnd, SW_SHOW);
SetWindowPos(pem_wpa->hWnd, HWND_TOP, pem_wgr->rect.left, pem_wgr->rect.top,
nWidthMenu, nHeightMenu, SWP_SHOWWINDOW);
return IR_P;
case CMD_WGI_VFROLLTOEND:
case CMD_WGI_VBROLLTOEND:
n = pem_wdl->ctrls.num-pem->nScrCtrl;
if(CMD_WGI_VFROLLTOEND == Act)
{
delta = pem_wgr->rect.bottom - pem_wgr->rect.top - (*ppACtrl)[n-1].rect.bottom;
if(0 == delta)
return IR_P;
}else
{
delta = -(*ppACtrl)[0].rect.top;
if(0 == delta)
return IR_P;
}
for(i=0; i<n; i++)
{
(*ppACtrl)[i].rect.top += delta;
(*ppACtrl)[i].rect.bottom += delta;
wpi.x = (*ppACtrl)[i].rect.left;
wpi.y = (*ppACtrl)[i].rect.top;
wpi.cx = (*ppACtrl)[i].rect.right - (*ppACtrl)[i].rect.left;
wpi.cy = (*ppACtrl)[i].rect.bottom - (*ppACtrl)[i].rect.top;
VO_Interact2((*ppACtrl)[i].pCtrl, SET_WGI_WINDOWPOS, (BYTE*)&wpi, sizeof(WINPOSINFO), &caller);
}
return IR_P;
case CMD_WGI_HFROLLTOEND:
case CMD_WGI_HBROLLTOEND:
return IR_P;
default:
break;
}
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_INTERACT0;
}
/**
*
* 名称:WMenu_Interact1
*/
static IRESULT WMenu_Interact1(OBJECT* This, ACTION Act, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
VR caller;
EM_WMENU* pem = (EM_WMENU*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
SI32 delta;
int flag;
caller.cr = pCaller->cr;
caller.mr = This->OID;
switch(Act)
{
case CMD_WGI_HFPAGE:
case CMD_WGI_HBPAGE:
return IR_P;
case CMD_WGI_VFPAGE:
case CMD_WGI_VBPAGE:
delta = pem_wgr->rect.bottom - pem_wgr->rect.top;
flag = CMD_WGI_VFPAGE == Act ? 0 : 1;
*(float*)OStrm = RollAndCalculateScale2End(This, delta, flag, &caller);
*pQty = sizeof(float);
return IR_P;
default:
break;
}
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_INTERACT1;
}
/**
*
* 名称:WMenu_Interact2
*/
static IRESULT WMenu_Interact2(OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, const VR* pCaller)
{
VR caller;
EM_WMENU* pem = (EM_WMENU*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WDIALOG* pem_wdl = (EM_WDIALOG*)pem->pWDialog->pEM;
CONTROL** ppACtrl = &pem_wdl->ctrls.pACtrl;
INIT_WMENU* piwmu;
SI32 delta;
WINPOSINFO wpi;
int i, n, m;
caller.cr = pCaller->cr;
caller.mr = This->OID;
switch(Act)
{
case CMD_INITIALIZE:
assert(sizeof(INIT_WMENU) == Qty);
piwmu = (INIT_WMENU*)IStrm;
pem->pfirstmit = piwmu->pfirstmit;
pem->style = piwmu->style;
pem->curitem = -1;
pem->crMITNormal = piwmu->crMITNormal;
pem->crMITOver = piwmu->crMITOver;
pem->crMITDown = piwmu->crMITDown;
pem->crMITDisable = piwmu->crMITDisable;
pem->GetBitmapsForItem = piwmu->GetBitmapsForItem;
pem->GetBitmapsForVScrollBar = piwmu->GetBitmapsForVScrollBar;
return IR_P;
case CMD_WGI_VFROLL2:
case CMD_WGI_VBROLL2:
assert(sizeof(SI32) == Qty);
delta = *(SI32*)IStrm;
n = pem_wdl->ctrls.num - pem->nScrCtrl;
if(CMD_WGI_VFROLL2 == Act)
{
m = pem_wgr->rect.bottom - pem_wgr->rect.top;
if((*ppACtrl)[n-1].rect.bottom == m)
return IR_P;
m = (*ppACtrl)[n-1].rect.bottom - m;
if(delta > m)
delta = m;
delta = - delta;
}else
{
m = (*ppACtrl)[0].rect.top;
if(0 == m)
return IR_P;
if(delta > -m)
delta = -m;
}
for(i=0; i<n; i++)
{
(*ppACtrl)[i].rect.top += delta;
(*ppACtrl)[i].rect.bottom += delta;
wpi.x = (*ppACtrl)[i].rect.left;
wpi.y = (*ppACtrl)[i].rect.top;
wpi.cx = (*ppACtrl)[i].rect.right - (*ppACtrl)[i].rect.left;
wpi.cy = (*ppACtrl)[i].rect.bottom - (*ppACtrl)[i].rect.top;
VO_Interact2((*ppACtrl)[i].pCtrl, SET_WGI_WINDOWPOS, (BYTE*)&wpi, sizeof(WINPOSINFO), &caller);
}
return IR_P;
case CMD_WGI_HFROLL2:
case CMD_WGI_HBROLL2:
assert(sizeof(SI32) == Qty);
return IR_P;
default:
break;
}
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_INTERACT2;
}
/**
*
* 名称:WMenu_Interact3
*/
static IRESULT WMenu_Interact3(OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
VR caller;
int flag;
caller.cr = pCaller->cr;
caller.mr = This->OID;
switch(Act)
{
case CMD_WGI_VFROLL3:
case CMD_WGI_VBROLL3:
assert(sizeof(SI32) == Qty);
assert(sizeof(float) == Cty);
flag = CMD_WGI_VFROLL3 == Act ? 0 : 1;
*(float*)OStrm = RollAndCalculateScale2End(This, *(SI32*)IStrm, flag, &caller);
*pQty = sizeof(float);
return IR_P;
case CMD_WGI_HFROLL3:
case CMD_WGI_HBROLL3:
assert(sizeof(SI32) == Qty);
return IR_P;
default:
break;
}
/* 在上面完成接口自己的任务。*/
SBO_OBJECT_INTERACT3;
}
/**
*
* 名称:WMenu_Close
*/
static IRESULT WMenu_Close(OBJECT* This, const VR* pCaller)
{
VR caller;
EM_WMENU* pem = (EM_WMENU*)This->pEM;
EM_WPANEL* pem_wpa = (EM_WPANEL*)pem->pWPanel->pEM;
OBS_OBJECT_CLOSE_;
/* 在下面完成接口自己的任务。*/
caller.cr = pCaller->cr;
caller.mr = This->OID;
if(0 == This->RefCnt)
{
SendMessage(pem_wpa->hWnd, WM_CLOSE, 0, 0);
if(pem->pSubMenu)
{
VO_Close(pem->pSubMenu, &caller);
DestroyObject(pem->pSubMenu);
}
return IR_P_RCZERO;
}
return IR_P;
}
/*========================+ TOG +========================*/
/**
*
* 名称:TOG_WMenu
*/
VOID TOG_WMenu(OBJECT* pObj)
{
pObj->Open = WMenu_Open;
pObj->Input = WMenu_Input;
pObj->Output = WMenu_Output;
pObj->IOput = WMenu_IOput;
pObj->Interact0 = WMenu_Interact0;
pObj->Interact1 = WMenu_Interact1;
pObj->Interact2 = WMenu_Interact2;
pObj->Interact3 = WMenu_Interact3;
pObj->Close = WMenu_Close;
}
/*=======================+ IRF(s) +======================*/
/* ... */
/*====================+ Function(s) +====================*/
/**
*
* 名称:RegisterClass
* 描述:
*/
static ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WMenuProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = gs_szWindowClass;
return RegisterClass(&wc);
}
/**
*
* 名称:WMenuProc
* 描述:Mesage handler for WMenu.
*/
static LRESULT CALLBACK WMenuProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
VR caller;
OBJECT* This;
EM_WMENU* pem ;
EM_WPANEL* pem_wpa;
EM_WGRINTERFACE* pem_wgr;
EM_WDIALOG* pem_wdl;
CONTROL** ppACtrl;
MENUINFO mif;
PAINTSTRUCT ps;
caller.mr = OID_MAIN;
memset(&mif, 0, sizeof(MENUINFO));
switch (message)
{
case WM_INITDIALOG:
This = (OBJECT*)GetWindowLong(hWnd, GWL_USERDATA);
pem = (EM_WMENU*)This->pEM;
pem_wdl = (EM_WDIALOG*)pem->pWDialog->pEM;
ppACtrl = &pem_wdl->ctrls.pACtrl;
caller.cr = This->OID;
VO_Interact0(pem->pWDialog, LOD_WGI_SKIN0, &caller);
break;
case WM_PAINT:
if(NULL == (This = (OBJECT*)GetWindowLong(hWnd, GWL_USERDATA)))
break;
pem = (EM_WMENU*)This->pEM;
pem_wdl = (EM_WDIALOG*)pem->pWDialog->pEM;
BeginPaint(hWnd, &ps);
pem_wdl->pWndProc(hWnd, message, wParam, lParam);
EndPaint(hWnd, &ps);
return TRUE;
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
This = (OBJECT*)GetWindowLong(hWnd, GWL_USERDATA);
pem = (EM_WMENU*)This->pEM;
pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
pem_wpa = (EM_WPANEL*)pem->pWPanel->pEM;
pem_wdl = (EM_WDIALOG*)pem->pWDialog->pEM;
caller.cr = This->OID;
ppACtrl = &pem_wdl->ctrls.pACtrl;
pem_wdl->pWndProc(hWnd, message, wParam, lParam);
if(WM_MOUSEMOVE == message)
{
if(pem_wdl->ctrls.icwf > -1 && pem_wdl->ctrls.icwf < pem_wdl->ctrls.num - pem->nScrCtrl)
{
if(pem_wdl->ctrls.icwf != pem->curitem)
{
if(pem->pSubMenu)
{
VO_Close(pem->pSubMenu, &caller);
DestroyObject(pem->pSubMenu);
}
if(NULL != (pem->pfirstmit + pem_wdl->ctrls.icwf)->nextlv)
{
mif.pfirstmit = (pem->pfirstmit + pem_wdl->ctrls.icwf)->nextlv;
mif.style = 0;
mif.style |= MS_AUTOWIDTH | MS_AUTOHEIGHT;
mif.bSitu = FALSE;
mif.hBmpBkgd = pem_wgr->hBmpCurrent;
mif.hFont = pem_wgr->ti.font;
mif.crMITNormal = pem->crMITNormal;
mif.crMITOver = pem->crMITOver;
mif.crMITDown = pem->crMITDown;
mif.crMITDisable = pem->crMITDisable;
mif.GetBitmapsForItem = pem->GetBitmapsForItem;
pem->pSubMenu = PopMenu((*ppACtrl)[pem_wdl->ctrls.icwf].pCtrl, pem_wgr->pParentWnd, &mif, &caller);
}
pem->curitem = pem_wdl->ctrls.icwf;
}
}
}else if(WM_LBUTTONUP == message)
{
if(pem_wdl->ctrls.icwf > -1 && pem_wdl->ctrls.icwf < pem_wdl->ctrls.num - pem->nScrCtrl && pem_wdl->ctrls.ichf < pem_wdl->ctrls.num - pem->nScrCtrl)
VO_Interact2(pem_wgr->pParentWnd, MSG_WGI_ONMENUITEM, (BYTE*)&(pem->pfirstmit+pem_wdl->ctrls.icwf)->id, sizeof(int), &caller);
}
break;
case WM_ERASEBKGND:
return TRUE; // 消除移动窗口闪烁。
case WM_CLOSE:
DestroyWindow(hWnd);
return TRUE;
default:
if(NULL == (This = (OBJECT*)GetWindowLong(hWnd, GWL_USERDATA)))
break;
pem = (EM_WMENU*)This->pEM;
pem_wdl = (EM_WDIALOG*)pem->pWDialog->pEM;
return pem_wdl->pWndProc(hWnd, message, wParam, lParam);
}
return TRUE;
}
/**
*
* NAME: CalculateWidthOfText
*/
static int CalculateWidthOfText(HDC hdc, TCHAR* text, BYTKTY len)
{
BYTKTY i;
int n;
int width = 0;
for(i = 0; i < len; i++)
{
GetCharWidth32(hdc, (UINT)text[i], (UINT)text[i], &n);
width += n;
}
return width;
}
/**
*
* NAME: RollAndCalculateScale2End
* PARA: -- flag --
* 0 - vertically forward, 1 - vertically backward
* 2 - horizontally forward, 3 - horizontally backward
*/
static float RollAndCalculateScale2End(OBJECT* This, SI32 delta, int flag, const VR* pCaller)
{
EM_WMENU* pem = (EM_WMENU*)This->pEM;
EM_WGRINTERFACE* pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
EM_WDIALOG* pem_wdl = (EM_WDIALOG*)pem->pWDialog->pEM;
CONTROL** ppACtrl = &pem_wdl->ctrls.pACtrl;
WINPOSINFO wpi;
float fSCtoEnd;
int i, n, m;
n = pem_wdl->ctrls.num - pem->nScrCtrl;
do
{
if(0 == flag)
{
m = pem_wgr->rect.bottom - pem_wgr->rect.top;
if((*ppACtrl)[n-1].rect.bottom == m)
{
fSCtoEnd = 0.0;
break;
}
m = (*ppACtrl)[n-1].rect.bottom - m;
if(delta > m)
delta = m;
delta = - delta;
}else if(1 == flag)
{
m = (*ppACtrl)[0].rect.top;
if(0 == m)
{
fSCtoEnd = 0.0;
break;
}
if(delta > -m)
delta = -m;
}else
{
assert(0);
}
for(i=0; i<n; i++)
{
(*ppACtrl)[i].rect.top += delta;
(*ppACtrl)[i].rect.bottom += delta;
wpi.x = (*ppACtrl)[i].rect.left;
wpi.y = (*ppACtrl)[i].rect.top;
wpi.cx = (*ppACtrl)[i].rect.right - (*ppACtrl)[i].rect.left;
wpi.cy = (*ppACtrl)[i].rect.bottom - (*ppACtrl)[i].rect.top;
VO_Interact2((*ppACtrl)[i].pCtrl, SET_WGI_WINDOWPOS, (BYTE*)&wpi, sizeof(WINPOSINFO), pCaller);
}
if(0 == flag)
{
m = pem_wgr->rect.bottom - pem_wgr->rect.top;
fSCtoEnd = (float) ((*ppACtrl)[n-1].rect.bottom - m) / ((*ppACtrl)[n-1].rect.bottom - (*ppACtrl)[0].rect.top);
break;
}else if(1 == flag)
{
m = -(*ppACtrl)[0].rect.top;
fSCtoEnd = (float) m / ((*ppACtrl)[n-1].rect.bottom - (*ppACtrl)[0].rect.top);
break;
}else
{
assert(0);
}
}while(0);
return fSCtoEnd;
}