WGI的WDialog.c文件源代码


/**
 *
 * 文 件 名:WDialog.c
 *
 * 描    述:
 *
 * 创 建 者:赵平智   <[email protected]>
 *
 * 创建日期:20091116
 *
 * 备    注:
 *
 *
 * * 维护历史 *
 *
 *   <日期>                <修改者>
 *   20091218               赵平智
 *   问题发现者:St.Nicholas <[email protected]>
 *   问题描述:当鼠标按住窗口边缘快速移动窗口时,窗口很容易与鼠标脱离。
 *   该问题已解决。解决办法:向窗口发送 WM_NCLBUTTONDOWN 消息并发送 HTCAPTION 数值。
 *
 **/

#include "WDialog.h"
#include "../../../se/se.h"

static LRESULT CALLBACK DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static void LoadSkin(OBJECT* This, TCHAR* szBitmapFile, const VR* pCaller);
static void  Paint(OBJECT* This, const VR* pCaller);

/*=====================+ OICC label +====================*/

/*<oicc>*/
/*<ibn> WPanel </ibn>*/
/*<crt>*/
/*</crt>*/
/*</oicc>*/

/*=====================+ Interface +=====================*/

/**
*
* 名称:WDialog_Open
*/
static IRESULT  WDialog_Open(OBJECT* This, const VR* pCaller)
{
 EM_WDIALOG* pem = (EM_WDIALOG*)This->pEM;

 OBS_OBJECT_OPEN_;

 /* 在下面完成接口自己的任务。*/

 if(1 == This->RefCnt)
 {
  pem->pWGrinterface = GetBN(This, MSN_WGRINTERFACE);
  pem->pWPanel = GetBN(This, MSN_WPANEL);
  pem->pWndProc = DialogProc;
 }

 return IR_P;
}

/**
*
* 名称:WDialog_Input
*/
static IRESULT  WDialog_Input(OBJECT* This, BYTE* IStrm, BYTKTY Qty, const VR* pCaller)
{

 /* ... */


 /* 在上面完成接口自己的任务。*/

 SBO_OBJECT_INPUT;
}

/**
*
* 名称:WDialog_Output
*/
static IRESULT  WDialog_Output(OBJECT* This, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{

 /* ... */


 /* 在上面完成接口自己的任务。*/

 SBO_OBJECT_OUTPUT;
}

/**
*
* 名称:WDialog_IOput
*/
static IRESULT  WDialog_IOput(OBJECT* This, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{

 /* ... */


 /* 在上面完成接口自己的任务。*/

 SBO_OBJECT_IOPUT;
}

/**
*
* 名称:WDialog_Interact0
*/
static IRESULT  WDialog_Interact0(OBJECT* This, ACTION Act, const VR* pCaller)
{
 VR      caller;
 EM_WDIALOG*  pem = (EM_WDIALOG*)This->pEM;
 EM_WGRINTERFACE*  pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
 EM_WPANEL*        pem_wpa = (EM_WPANEL*)pem->pWPanel->pEM;

 caller.cr = pCaller->cr;
 caller.mr = This->OID;

 switch(Act)
 {
 case LOD_WGI_SKIN0:
  LoadSkin(This, NULL, &caller);
  return IR_P;
 case  CMD_WGI_ENABLE:
  pem_wgr->style &= ~GS_DISABLED;
  EnableWindow(pem_wpa->hWnd, TRUE);
  return IR_P;
 case  CMD_WGI_DISABLE:
  pem_wgr->style |= GS_DISABLED;
  EnableWindow(pem_wpa->hWnd, FALSE);
  return IR_P;
 case CLR_WGI_TEXT:
  VO_Interact0(pem->pWGrinterface, CLR_WGI_TEXT, &caller);
  LoadSkin(This, NULL, &caller);
  return IR_P;
 default:
  break;
 }


 /* 在上面完成接口自己的任务。*/

 SBO_OBJECT_INTERACT0;
}

/**
*
* 名称:WDialog_Interact1
*/
static IRESULT  WDialog_Interact1(OBJECT* This, ACTION Act, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{

 /* ... */


 /* 在上面完成接口自己的任务。*/

 SBO_OBJECT_INTERACT1;
}

/**
*
* 名称:WDialog_Interact2
*/
static IRESULT  WDialog_Interact2(OBJECT* This, ACTION  Act, BYTE* IStrm, BYTKTY Qty, const VR* pCaller)
{
 VR    caller;
 EM_WDIALOG*       pem = (EM_WDIALOG*)This->pEM;
 EM_WGRINTERFACE*  pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
 EM_WPANEL*        pem_wpa = (EM_WPANEL*)pem->pWPanel->pEM;
 INIT_WDIALOG*     piwdl;

 caller.cr = pCaller->cr;
 caller.mr = This->OID;

 switch(Act)
 {
 case CMD_INITIALIZE:
  assert(sizeof(INIT_WDIALOG) == Qty);
  piwdl = (INIT_WDIALOG*)IStrm;
  pem->style = piwdl->style;
  pem->ctrls.icwf = -1;
  pem->ctrls.ichf = -1;
  pem->ctrls.iccf = -1;
  return IR_P;
 case SET_WGI_WINDOWPOS:
  VO_Interact2(pem->pWGrinterface, SET_WGI_WINDOWPOS, IStrm, sizeof(WINPOSINFO), &caller);
  SetWindowPos(pem_wpa->hWnd, HWND_TOP, pem_wgr->rect.left, pem_wgr->rect.top,
   pem_wgr->rect.right - pem_wgr->rect.left, pem_wgr->rect.bottom - pem_wgr->rect.top, SWP_SHOWWINDOW);
  return IR_P;
 case LOD_WGI_SKIN2:
  assert(Qty > 0);
  LoadSkin(This, (TCHAR*)IStrm, &caller);
  return IR_P;
 case SET_WGI_TIRECT:
  assert(Qty >= sizeof(RECT));
  pem_wgr->ti.rect = *(RECT*)IStrm;
  VO_Interact2(pem->pWGrinterface, SET_WGI_TIRECT, IStrm, Qty, &caller);
  LoadSkin(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;
  LoadSkin(This, NULL, &caller);
  return IR_P;
 default:
  break;
 }


 /* 在上面完成接口自己的任务。*/

 SBO_OBJECT_INTERACT2;
}

/**
*
* 名称:WDialog_Interact3
*/
static IRESULT  WDialog_Interact3(OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{

 /* ... */


 /* 在上面完成接口自己的任务。*/

 SBO_OBJECT_INTERACT3;
}

/**
*
* 名称:WDialog_Close
*/
static IRESULT  WDialog_Close(OBJECT* This, const VR* pCaller)
{
 VR      caller;
 EM_WDIALOG*        pem = (EM_WDIALOG*)This->pEM;
 EM_WGRINTERFACE*   pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
 CONTROL**          ppACtrl = &pem->ctrls.pACtrl;
 int                i;

 OBS_OBJECT_CLOSE_;

 /* 在下面完成接口自己的任务。*/

 caller.cr = pCaller->cr;
 caller.mr = This->OID;

 if(0 == This->RefCnt)
 {
  if(*ppACtrl)
  {
   for(i = 0; i<pem->ctrls.num; i++)
   {
    if((*ppACtrl + i)->pCtrl != NULL)
    {
     VO_Close((*ppACtrl)[i].pCtrl, &caller);
     DestroyObject((*ppACtrl)[i].pCtrl); /* 销毁动态创建的对象。*/
    }
   }
   free(pem->ctrls.pACtrl);
   pem->ctrls.pACtrl = NULL;
  }

  if(pem_wgr->hBmpCurrent)
  {
   DeleteObject(pem_wgr->hBmpCurrent);
   pem_wgr->hBmpCurrent = NULL;
  }

  return IR_P_RCZERO;
 }

 return IR_P;
}

/*========================+ TOG +========================*/

/**
*
* 名称:TOG_WDialog
*/
VOID  TOG_WDialog(OBJECT* pObj)
{
 pObj->Open = WDialog_Open;
 pObj->Input = WDialog_Input;
 pObj->Output = WDialog_Output;
 pObj->IOput = WDialog_IOput;
 pObj->Interact0 = WDialog_Interact0;
 pObj->Interact1 = WDialog_Interact1;
 pObj->Interact2 = WDialog_Interact2;
 pObj->Interact3 = WDialog_Interact3;
 pObj->Close = WDialog_Close;
}

/*=======================+ IRF(s) +======================*/
/* ... */

/*====================+ Function(s) +====================*/

/**
*
* 名称:DialogProc
* 描述:Mesage handler for dialog.
*/
static LRESULT CALLBACK DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 int         i, n;
 POINT       pt, pt2;
 CONTROL**   ppACtrl;
 VR          caller;
 OBJECT*     This;
 EM_WGRINTERFACE*   pem_wgr, *pem_ctrwgr;
 EM_WPANEL*         pem_wpa;
 EM_WDIALOG*        pem;


 caller.cr = OID_MAIN;

 switch(message)
 {
 case WM_PAINT: 
  This = GetBN((OBJECT*)GetWindowLong(hWnd, GWL_USERDATA), MSN_WDIALOG);
  pem = (EM_WDIALOG*)This->pEM;
  pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
  caller.mr = This->OID;
  Paint(This, &caller); 
  return TRUE;
 case WM_MOVE:
  This = GetBN((OBJECT*)GetWindowLong(hWnd, GWL_USERDATA), MSN_WDIALOG);
  pem = (EM_WDIALOG*)This->pEM;
  pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
  n = pem_wgr->rect.right - pem_wgr->rect.left;
  pem_wgr->rect.left = GET_X_LPARAM(lParam);
  pem_wgr->rect.right = pem_wgr->rect.left + n;
  n = pem_wgr->rect.bottom - pem_wgr->rect.top;
  pem_wgr->rect.top = GET_Y_LPARAM(lParam);
  pem_wgr->rect.bottom = pem_wgr->rect.top + n;
  break;
 case WM_MOUSEMOVE:
  This = GetBN((OBJECT*)GetWindowLong(hWnd, GWL_USERDATA), MSN_WDIALOG);
  pem = (EM_WDIALOG*)This->pEM;
  pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
  pem_wpa = (EM_WPANEL*)pem->pWPanel->pEM;
  caller.mr = This->OID;

  pt.x = GET_X_LPARAM(lParam);
  pt.y = GET_Y_LPARAM(lParam);
  pt2.x = GET_X_LPARAM(lParam) - pem_wgr->rcfi.left;
  pt2.y = GET_Y_LPARAM(lParam) - pem_wgr->rcfi.top;


  if(wParam != MK_LBUTTON)
  {
   ppACtrl = &pem->ctrls.pACtrl;
   if(-1 == pem->ctrls.icwf)
   {
    for(i = 0; i < pem->ctrls.num; i++)
    {
     if((*ppACtrl + i)->pCtrl != NULL)
     {
      pem_ctrwgr = (EM_WGRINTERFACE*)GetEMofBN((*ppACtrl + i)->pCtrl, MSN_WGRINTERFACE);
      if(PtInRect(&(*ppACtrl + i)->rect, pt) && !(pem_ctrwgr->style & GS_DISABLED))
      {
       pem->ctrls.icwf = i;
       VO_Interact2((*ppACtrl + i)->pCtrl, MSG_WGI_FOCUSOVERMOVE, (BYTE*)&pt2, sizeof(POINT), &caller);
       return TRUE;
      }
     }
    }
   }else if(!PtInRect(&((*ppACtrl + pem->ctrls.icwf)->rect), pt))
   {
    pem_ctrwgr = (EM_WGRINTERFACE*)GetEMofBN((*ppACtrl + pem->ctrls.icwf)->pCtrl, MSN_WGRINTERFACE);
    if(!(pem_ctrwgr->style & GS_DISABLED))
     VO_Interact2((*ppACtrl + pem->ctrls.icwf)->pCtrl, MSG_WGI_FOCUSOVERLEAVE, (BYTE*)&pt2, sizeof(POINT), &caller);
    pem->ctrls.icwf = -1;
    return TRUE;
   }else
   {
    VO_Interact2((*ppACtrl + pem->ctrls.icwf)->pCtrl, MSG_WGI_FOCUSOVERMOVE, (BYTE*)&pt2, sizeof(POINT), &caller);
    return TRUE;
   }
  }else // wParam == MK_LBUTTON
  {
   ppACtrl = &pem->ctrls.pACtrl;
   if(-1 == pem->ctrls.icwf)
   {
    for(i = 0; i<pem->ctrls.num; i++)
    {
     if((*ppACtrl + i)->pCtrl != NULL)
     {
      pem_ctrwgr = (EM_WGRINTERFACE*)GetEMofBN((*ppACtrl + i)->pCtrl, MSN_WGRINTERFACE);
      if(PtInRect(&(*ppACtrl + i)->rect, pt) && !(pem_ctrwgr->style & GS_DISABLED))
      {
       pem->ctrls.icwf = i;
       break;
      }
     }
    }
   }else if(!PtInRect(&((*ppACtrl + pem->ctrls.icwf)->rect), pt))
   {
    pem->ctrls.icwf = -1;
   }

   if(-1 == pem->ctrls.icwf && -1 == pem->ctrls.iccf)
   {
    if(!(pem_wgr->style & GS_IMMOVABLE))
     PostMessage(pem_wpa->hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
   }else if(pem->ctrls.iccf > -1)
   {
    VO_Interact2((pem->ctrls.pACtrl + pem->ctrls.iccf)->pCtrl, MSG_WGI_FOCUSCAPTUREDMOVE, (BYTE*)&pt2, sizeof(POINT), &caller);
   }
  }
  return TRUE;
 case WM_LBUTTONDOWN:
  This = GetBN((OBJECT*)GetWindowLong(hWnd, GWL_USERDATA), MSN_WDIALOG);
  pem = (EM_WDIALOG*)This->pEM;
  pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
  caller.mr = This->OID;

  pt.x = GET_X_LPARAM(lParam);
  pt.y = GET_Y_LPARAM(lParam);
  pt2.x = GET_X_LPARAM(lParam) - pem_wgr->rcfi.left;
  pt2.y = GET_Y_LPARAM(lParam) - pem_wgr->rcfi.top;

  pem->ctrls.icwf = -1; // 触摸屏需要

  ppACtrl = &pem->ctrls.pACtrl;
  if(pem->ctrls.icwf > -1)
  {
   if(pem->ctrls.ichf > -1)
   {
    if(pem->ctrls.icwf != pem->ctrls.ichf)
    {
     VO_Interact2((*ppACtrl + pem->ctrls.ichf)->pCtrl, MSG_WGI_FOCUSLOSE, (BYTE*)&pt2, sizeof(POINT), &caller);
     pem->ctrls.ichf = pem->ctrls.icwf;
    }
   }else
   {
    pem->ctrls.ichf = pem->ctrls.icwf;
   }

   VO_Interact2((*ppACtrl + pem->ctrls.icwf)->pCtrl, MSG_WGI_FOCUSBT1DOWN, (BYTE*)&pt2, sizeof(POINT), &caller);
   pem->ctrls.iccf = pem->ctrls.icwf;
   VO_Interact2((*ppACtrl + pem->ctrls.iccf)->pCtrl, MSG_WGI_FOCUSCAPTURE, (BYTE*)&pt2, sizeof(POINT), &caller);

   return TRUE;
  }

  pt2.x = GET_X_LPARAM(lParam) - pem_wgr->rcfi.left;
  pt2.y = GET_Y_LPARAM(lParam) - pem_wgr->rcfi.top;

  for(i = 0; i<pem->ctrls.num; i++)
  {
   if((*ppACtrl + i)->pCtrl != NULL)
   {
    pem_ctrwgr = (EM_WGRINTERFACE*)GetEMofBN((*ppACtrl + i)->pCtrl, MSN_WGRINTERFACE);
    if(PtInRect(&(*ppACtrl + i)->rect,  pt) && !(pem_ctrwgr->style & GS_DISABLED))
    {
     pem->ctrls.icwf = i;  // 触摸屏需要
     if(pem->ctrls.ichf > -1)
     {
      if(i != pem->ctrls.ichf)
      {
       VO_Interact2((pem->ctrls.pACtrl + pem->ctrls.ichf)->pCtrl, MSG_WGI_FOCUSLOSE, (BYTE*)&pt2, sizeof(POINT), &caller);
       pem->ctrls.ichf = i;
      }
     }else
     {
      pem->ctrls.ichf = i;
     }
     
     VO_Interact2((*ppACtrl + i)->pCtrl, MSG_WGI_FOCUSBT1DOWN, (BYTE*)&pt2, sizeof(POINT), &caller);
     pem->ctrls.iccf = pem->ctrls.icwf;
     VO_Interact2((*ppACtrl + i)->pCtrl, MSG_WGI_FOCUSCAPTURE, (BYTE*)&pt2, sizeof(POINT), &caller);
     
     return TRUE;
    }
   }
  }

  return TRUE;
 case WM_LBUTTONUP:
  This = GetBN((OBJECT*)GetWindowLong(hWnd, GWL_USERDATA), MSN_WDIALOG);
  pem = (EM_WDIALOG*)This->pEM;
  pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
  caller.mr = This->OID;

  pt.x = GET_X_LPARAM(lParam);
  pt.y = GET_Y_LPARAM(lParam);
  pt2.x = GET_X_LPARAM(lParam) - pem_wgr->rcfi.left;
  pt2.y = GET_Y_LPARAM(lParam) - pem_wgr->rcfi.top;

  ppACtrl = &pem->ctrls.pACtrl;
  if(pem->ctrls.iccf > -1)
  {
   VO_Interact2((*ppACtrl + pem->ctrls.iccf)->pCtrl, MSG_WGI_FOCUSRELEASE, (BYTE*)&pt2, sizeof(POINT), &caller);
   pem->ctrls.iccf = -1;
  }

  if(pem->ctrls.icwf != -1)
  {
   pem_ctrwgr = (EM_WGRINTERFACE*)GetEMofBN((*ppACtrl + pem->ctrls.icwf)->pCtrl, MSN_WGRINTERFACE);
   if(!(pem_ctrwgr->style & GS_DISABLED))
    VO_Interact2((*ppACtrl + pem->ctrls.icwf)->pCtrl, MSG_WGI_FOCUSBT1UP, (BYTE*)&pt2, sizeof(POINT), &caller);
   if(!PtInRect(&((*ppACtrl + pem->ctrls.icwf)->rect),  pt))
   {
    VO_Interact2((*ppACtrl + pem->ctrls.icwf)->pCtrl, MSG_WGI_FOCUSOVERLEAVE, (BYTE*)&pt2, sizeof(POINT), &caller);
    for(i = 0; (i < pem->ctrls.num) && (i != pem->ctrls.icwf); i++)
    {
     if((*ppACtrl + i)->pCtrl != NULL)
     {
      pem_ctrwgr = (EM_WGRINTERFACE*)GetEMofBN((*ppACtrl + i)->pCtrl, MSN_WGRINTERFACE);
      if(PtInRect(&(*ppACtrl + i)->rect,  pt) && !(pem_ctrwgr->style & GS_DISABLED))
      {
       pem->ctrls.icwf = i;
       VO_Interact2((*ppACtrl + i)->pCtrl, MSG_WGI_FOCUSOVERMOVE, (BYTE*)&pt2, sizeof(POINT), &caller);
       return TRUE;
      }
     }
    }

    pem->ctrls.icwf = -1;
    return TRUE;
   }
  }else
  {
   for(i = 0; i<pem->ctrls.num; i++)
   {
    if((*ppACtrl + i)->pCtrl != NULL)
    {
     pem_ctrwgr = (EM_WGRINTERFACE*)GetEMofBN((*ppACtrl + i)->pCtrl, MSN_WGRINTERFACE);
     if(PtInRect(&(*ppACtrl + i)->rect,  pt) && !(pem_ctrwgr->style & GS_DISABLED))
     {
      VO_Interact2((*ppACtrl + i)->pCtrl, MSG_WGI_FOCUSOVERMOVE, (BYTE*)&pt2, sizeof(POINT), &caller);
      pem->ctrls.icwf = i;
      break;
     }
    }
   }
  }

  return TRUE;
 default:
        return DefWindowProc(hWnd, message, wParam, lParam);
 }

 return TRUE;
}


/**
*
* 名称:LoadSkin
* 描述:
*/
static void LoadSkin(OBJECT* This, TCHAR* szBitmapFile, const VR* pCaller)
{
 EM_WDIALOG*        pem = (EM_WDIALOG*)This->pEM;
 EM_WGRINTERFACE*   pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
 EM_WPANEL*         pem_wpa = (EM_WPANEL*)pem->pWPanel->pEM;
 HDC                hdc, memdc1, memdc2;
    HBITMAP            hBitmap, hOldBmp1, hOldBmp2;
 CONTROL**          ppACtrl;
 HFONT              hOldFont;
 COLORREF           crOldColor;
 BITMAP             bm;
 int                i, w, h;
 
 hOldBmp1 = hOldBmp2 = 0;

 w = pem_wgr->rect.right - pem_wgr->rect.left;
 h = pem_wgr->rect.bottom - pem_wgr->rect.top;

 hdc = GetDC(pem_wpa->hWnd);

 memdc1 = CreateCompatibleDC(hdc);
 memdc2 = CreateCompatibleDC(hdc);

 if(szBitmapFile != NULL)
 {
  //hBitmap = LoadBitmap(pem_wgr->hInstance, szBitmapFile);
  hBitmap = (HBITMAP)LoadImage(pem_wgr->hInstance, szBitmapFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  GetObject(hBitmap, sizeof(bm), &bm);
  hOldBmp2 = SelectObject(memdc2, hBitmap);

  if(pem_wpa->hBmpBackground)
   DeleteObject(pem_wpa->hBmpBackground);
  pem_wpa->hBmpBackground = CreateCompatibleBitmap(hdc, w, h);
  hOldBmp1 = SelectObject(memdc1, pem_wpa->hBmpBackground);
  //BitBlt(memdc1, 0, 0, w, h, memdc2, 0, 0, SRCCOPY);
  StretchBlt(memdc1, 0, 0, w, h, memdc2, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);

  if(pem_wgr->hBmpCurrent)
   DeleteObject(pem_wgr->hBmpCurrent);
  pem_wgr->hBmpCurrent = CreateCompatibleBitmap(hdc, w, h);
  SelectObject(memdc1, pem_wgr->hBmpCurrent); 
  //BitBlt(memdc1, 0, 0, w, h, memdc2, 0, 0, SRCCOPY);
  StretchBlt(memdc1, 0, 0, w, h, memdc2, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
  DeleteObject(hBitmap);

  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);
   
   DrawText(memdc1, pem_wgr->ti.text, pem_wgr->ti.clen, &pem_wgr->ti.rect, pem_wgr->ti.format);
   
   if(pem_wgr->ti.font)
    SelectObject(memdc1, hOldFont);
   SetTextColor(memdc1, crOldColor);
  }
  
  SelectObject(memdc1, hOldBmp1); 

 }else if(pem_wgr->hBmpCurrent)
 {
  if(0 == pem_wpa->hBmpBackground)
  {
   GetObject(pem_wgr->hBmpCurrent, sizeof(bm), &bm);
   hOldBmp1 = SelectObject(memdc1, pem_wgr->hBmpCurrent); 
   pem_wpa->hBmpBackground = CreateCompatibleBitmap(hdc, w, h);
   hOldBmp2 = SelectObject(memdc2, pem_wpa->hBmpBackground);
   //BitBlt(memdc2, 0, 0, w, h, memdc1, 0, 0, SRCCOPY);
   StretchBlt(memdc2, 0, 0, w, h, memdc1, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
  }else
  {
   hOldBmp2 = SelectObject(memdc2, pem_wpa->hBmpBackground);
   DeleteObject(pem_wgr->hBmpCurrent);
  }

  pem_wgr->hBmpCurrent = CreateCompatibleBitmap(hdc, w, h);
  if(hOldBmp1)
   SelectObject(memdc1, pem_wgr->hBmpCurrent);
  else
   hOldBmp1 = SelectObject(memdc1, pem_wgr->hBmpCurrent);
  BitBlt(memdc1, 0, 0, w, h, memdc2, 0, 0, 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);
   
   DrawText(memdc1, pem_wgr->ti.text, pem_wgr->ti.clen, &pem_wgr->ti.rect, pem_wgr->ti.format);
   
   if(pem_wgr->ti.font)
    SelectObject(memdc1, hOldFont);
   SetTextColor(memdc1, crOldColor);
  }

  SelectObject(memdc1, hOldBmp1); 
 }
 
 ppACtrl = &pem->ctrls.pACtrl;
 for(i=0; i<pem->ctrls.num; i++)
  if((*ppACtrl + i)->pCtrl != NULL)
   VO_Interact0((pem->ctrls.pACtrl+i)->pCtrl, CMD_WGI_PREPAINT, pCaller);

 hOldBmp1 = SelectObject(memdc1, pem_wgr->hBmpCurrent);
 BitBlt(hdc, 0, 0, w, h, memdc1, 0, 0, SRCCOPY);
 
 ReleaseDC(pem_wpa->hWnd, hdc);
 
 SelectObject(memdc1, hOldBmp1);
 DeleteDC(memdc1);
 SelectObject(memdc2, hOldBmp2);
 DeleteDC(memdc2); 

 return;
}


/**
*
* 名称:Paint
* 描述:
*/
static void  Paint(OBJECT* This, const VR* pCaller)
{
 EM_WDIALOG*         pem = (EM_WDIALOG*)This->pEM;
 EM_WGRINTERFACE*    pem_wgr = (EM_WGRINTERFACE*)pem->pWGrinterface->pEM;
 EM_WPANEL*          pem_wpa = (EM_WPANEL*)pem->pWPanel->pEM;
 HDC                 hdc, memdc;
 HBITMAP             hOldBmp;
 int                 w, h;

 hdc = GetDC(pem_wpa->hWnd);

 memdc = CreateCompatibleDC(hdc);
 hOldBmp = SelectObject(memdc, pem_wgr->hBmpCurrent);
 w = pem_wgr->rect.right - pem_wgr->rect.left;
 h = pem_wgr->rect.bottom - pem_wgr->rect.top; 
 BitBlt(hdc, 0, 0, w, h, memdc, 0, 0, SRCCOPY);
 
 ReleaseDC(pem_wpa->hWnd, hdc);

 SelectObject(memdc, hOldBmp);
 DeleteDC(memdc);
 
 return;
}