123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 |
- // TabSheet.cpp : implementation file
- //
- #include "stdafx.h"
- #include "TabSheet.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- // constant string definitions here (or you can put it into resource string table)
- #define IDS_UTIL_TAB "TAB"
- #define IDS_UTIL_UXTHEME "UxTheme.dll"
- #define IDS_UTIL_THEMEACT "IsThemeActive"
- #define IDS_UTIL_THEMEOPN "OpenThemeData"
- #define IDS_UTIL_THEMEBCKG "DrawThemeBackground"
- /***********************************************************************************************************/
- /////////////////////////////////////////////////////////////////////////////
- // CTabSheet
- CTabSheet::CTabSheet()
- {
- m_nNumOfPages = 0;
- m_nCurrentPage = 0;
- m_eTabOrientation=e_tabBottom; // default initial orientation is: bottom
- }
- CTabSheet::~CTabSheet()
- {
- }
- BEGIN_MESSAGE_MAP(CTabSheet, CTabCtrl)
- //{{AFX_MSG_MAP(CTabSheet)
- ON_WM_LBUTTONDOWN()
- //}}AFX_MSG_MAP
- ON_WM_PAINT()
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CTabSheet message handlers
- BOOL CTabSheet::AddPage(LPCTSTR title, CDialog *pDialog,UINT ID)
- {
- if( MAXPAGE == m_nNumOfPages )
- return FALSE;
- m_nNumOfPages++;
- m_pPages[m_nNumOfPages-1] = pDialog;
- m_IDD[m_nNumOfPages-1] = ID;
- m_Title[m_nNumOfPages-1] = title;
- return TRUE;
- }
- void CTabSheet::SetRect()
- {
- CRect tabRect, itemRect;
- int nX, nY, nXc, nYc;
- GetClientRect(&tabRect);
- GetItemRect(0, &itemRect);
- nX=itemRect.left;
- nY=itemRect.bottom+1;
- nXc=tabRect.right-itemRect.left-2;
- nYc=tabRect.bottom-nY-2;
- m_pPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);
- for( int nCount=1; nCount < m_nNumOfPages; nCount++ )
- m_pPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);
- }
- void CTabSheet::Show()
- {
- for( int i=0; i < m_nNumOfPages; i++ )
- {
- m_pPages[i]->Create( m_IDD[i], this );
- InsertItem( i, m_Title[i] );
- }
- m_pPages[0]->ShowWindow(SW_SHOW);
- for( i=1; i < m_nNumOfPages; i++)
- m_pPages[i]->ShowWindow(SW_HIDE);
- SetRect();
- }
- void CTabSheet::OnLButtonDown(UINT nFlags, CPoint point)
- {
- CTabCtrl::OnLButtonDown(nFlags, point);
- if(m_nCurrentPage != GetCurFocus())
- {
- m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE);
- m_nCurrentPage=GetCurFocus();
- m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW);
- // m_pPages[m_nCurrentPage]->SetFocus();
- }
- }
- int CTabSheet::SetCurSel(int nItem)
- {
- if( nItem < 0 || nItem >= m_nNumOfPages)
- return -1;
- int ret = m_nCurrentPage;
- if(m_nCurrentPage != nItem )
- {
- m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE);
- m_nCurrentPage = nItem;
- m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW);
- // m_pPages[m_nCurrentPage]->SetFocus();
- CTabCtrl::SetCurSel(nItem);
- }
- return ret;
- }
- int CTabSheet::GetCurSel()
- {
- return CTabCtrl::GetCurSel();
- }
- void CTabSheet::OnPaint()
- {
- CPaintDC dc(this); // device context for painting
- // TODO: 在此处添加消息处理程序代码
- // 不为绘图消息调用 CTabCtrl::OnPaint()
- //AfxMessageBox("dd");
- CRect rcClip; rcClip.SetRectEmpty();
- dc.GetClipBox(rcClip);
- // 1st paint the tab body
- CRect rcPage,rcItem,rcClient;
- GetClientRect(&rcPage);
- rcClient=rcPage;
- AdjustRect(FALSE,rcPage);
-
- switch(m_eTabOrientation)
- { case e_tabTop: rcClient.top =rcPage.top -2; break;
- case e_tabBottom: rcClient.bottom=rcPage.bottom+3; break;
- case e_tabLeft: rcClient.left =rcPage.left -1; break;
- case e_tabRight: rcClient.right =rcPage.right +3; break;
- default: ASSERT(FALSE); return;
- }
- UINT uiVertBottm;
- uiVertBottm =(m_eTabOrientation&1)? 8:0; // 8=bottom
- uiVertBottm|=(m_eTabOrientation&2)?16:0; // 16=vertical
- UINT uiFlags=1|uiVertBottm; // 1=body
- DrawThemesXpTabItem(&dc, -1, rcClient,uiFlags); // TABP_PANE=9,0,'TAB'
-
- int nTab=GetItemCount(); // paint the tabs first and then the borders
- if(!nTab) return; // no tab pages added
- // 2nd paint the inactive tabs
- CRect ;
- TCHITTESTINFO hti; hti.flags=0;
- ::GetCursorPos(&hti.pt); ScreenToClient(&hti.pt);
- int ixHot=HitTest(&hti);
- int ixSel=GetCurSel();
-
- for(int ixTab=0; ixTab<nTab; ixTab++)
- { if(ixTab==ixSel)
- continue;
- VERIFY(GetItemRect(ixTab, &rcItem));
- if(m_eTabOrientation==e_tabLeft) rcItem.right++;
- uiFlags=uiVertBottm|(ixTab==ixHot?4:0); // 4= hot
- DrawThemesXpTabItem(&dc,ixTab,rcItem,uiFlags);
- }
- // 3rd paint the active selected tab
- VERIFY(GetItemRect(ixSel, &rcItem)); // now selected tab
- rcItem.InflateRect(2,2);
- if(m_eTabOrientation==e_tabTop) rcItem.bottom--;
- uiFlags=uiVertBottm|2; // 2= selected
- DrawThemesXpTabItem(&dc, ixSel, rcItem,uiFlags);
- }
- void CTabSheet::DrawThemesXpTabItem(CDC* pDC, int ixItem, const CRect& rcItem, UINT uiFlag)
- { // uiFlag(1/0):1=Type(body/tab);2=Sel(y/n);4=Hot(y/n);8=bBottom(y/n);16=rotate(y/n)
- BOOL bBody =(uiFlag& 1)?TRUE:FALSE;
- BOOL bSel =(uiFlag& 2)?TRUE:FALSE;
- BOOL bHot =(uiFlag& 4)?TRUE:FALSE;
- BOOL bBottom=(uiFlag& 8)?TRUE:FALSE; // mirror
- BOOL bVertic=(uiFlag&16)?TRUE:FALSE; // rotate
- BOOL bLeftTab=!bBottom && bVertic && !bBody;
- CSize szBmp=rcItem.Size();
- if(bVertic) SwapVars(szBmp.cx,szBmp.cy);
- // 1st draw background
- CDC dcMem; dcMem .CreateCompatibleDC(pDC);
- CBitmap bmpMem; bmpMem.CreateCompatibleBitmap(pDC,szBmp.cx,szBmp.cy);
- CBitmap* pBmpOld=dcMem.SelectObject(&bmpMem);
- CRect rcMem(CPoint(0,0),szBmp); if(bSel) rcMem.bottom++;
- if(bBody)
- DrawThemesPart(dcMem.GetSafeHdc(), 9, 0, (LPCSTR)IDS_UTIL_TAB, &rcMem); // TABP_PANE=9, 0, 'TAB'
- else DrawThemesPart(dcMem.GetSafeHdc(), 1, bSel?3:(bHot?2:1), (LPCSTR)IDS_UTIL_TAB, &rcMem);
- // TABP_TABITEM=1, TIS_SELECTED=3:TIS_HOT=2:TIS_NORMAL=1, 'TAB'
- // 2nd init some extra parameters
- BITMAPINFO biOut; ZeroMemory(&biOut,sizeof(BITMAPINFO)); // Fill local pixel arrays
- BITMAPINFOHEADER& bihOut=biOut.bmiHeader;
- bihOut.biSize =sizeof (BITMAPINFOHEADER);
- bihOut.biCompression=BI_RGB;
- bihOut.biPlanes=1; bihOut.biBitCount=24; // force as RGB: 3 bytes,24 bits -> good for rotating bitmap in any resolution
- bihOut.biWidth =szBmp.cx; bihOut.biHeight=szBmp.cy;
- int nBmpWdtPS=DWordAlign(szBmp.cx*3);
- int nSzBuffPS=((nBmpWdtPS*szBmp.cy)/8+2)*8;
- LPBYTE pcImg=NULL;
- if(bBottom || bVertic) { pcImg=new BYTE[nSzBuffPS]; ASSERT(pcImg); }
- int nStart=0,nLenSub=0;
- if(bBody && bBottom && !bVertic) nStart=3,nLenSub=4; // if bottom oriented flip the body contest only (no shadows were flipped)
- // 3rd if it is left oriented tab, draw tab context before mirroring or rotating (before GetDIBits)
- if(bVertic)
- { if(bBody || !bBottom) bihOut.biHeight=-szBmp.cy;
- if(!bBottom && !bBody && ixItem>=0) //
- { if(bSel) rcMem.bottom--;
- DrawTabItem(&dcMem, ixItem, rcMem, uiFlag); ixItem=-1;
- } } // rotate or mirror
- // 4th get bits (for rotate) and mirror: body=(all except top) tab=(all except top)
- if(bVertic || bBottom) // get bits:
- { GetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS);
- if(bBottom) // mirror: body=(bottom and right) tab=(bottom and right)
- { bihOut.biHeight=-szBmp.cy; // to mirror bitmap is eough to use negative height between Get/SetDIBits
- SetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS);
- if(bBody && bVertic) // when it is right oriented body -> flip twice, first flip border shadows, than flip shaded inside body again
- { nStart=2; nLenSub=4; bihOut.biHeight=szBmp.cy;
- GetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS);
- bihOut.biHeight=-szBmp.cy; // to mirror bitmap is eough to use negative height between Get/SetDIBits
- SetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS);
- } } }
- // 5th if it is bottom or right oriented tab, draw after mirroring background (do GetDIBits again)
- if(!bBody && ixItem>=0) //
- { if(bSel) rcMem.bottom--;
- DrawTabItem(&dcMem, ixItem, rcMem, uiFlag);
- if(bVertic) // if it is right tab, do GetDIBits again
- { bihOut.biHeight=-szBmp.cy;
- GetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS);
- } }
- // 6th: do rotate now, finaly
- if(bVertic) // force rotating bitmap as RGB -> good for any resolution
- { SwapVars(szBmp.cx,szBmp.cy);
- int nBmpWdtPD=DWordAlign(szBmp.cx*3);
- int nPadD=nBmpWdtPD-szBmp.cx*3;
- int nSzBuffPD=((nBmpWdtPD*szBmp.cy)/8+2)*8;
- LPBYTE pcImgRotate=new BYTE[nSzBuffPD]; ASSERT(pcImgRotate);
- int nWidth,nHeight=szBmp.cy,nHeight1=nHeight-1;
- //====================================
- //------------------------------------
- // here is the example how to speed up lengthy repeatetive processing by using inline assembler
- #define __USE_MASM__ // the same processing is in C and in asm. To use C -> comment the beginning of this line
- // Do the actual whole RGB bitmap rotating in C or assembler
- #ifndef __USE_MASM__
- LPBYTE pcImgS=pcImg;
- LPBYTE pcImgD=pcImgRotate;
- int ixHeight=0;
- BOOL bLast=FALSE;
- while(ixHeight<nHeight) // for all destination height lines
- { nWidth=szBmp.cx;
- if(ixHeight==nHeight1) { bLast=TRUE; nWidth--; }
-
- while(nWidth--)
- { *(PDWORD)pcImgD=*(PDWORD)pcImgS; // do all Rgb triplets read/write qicker as DWORD
- pcImgS+=nBmpWdtPS; // increment source in padded source lines
- pcImgD+=3; // increment destination in rgb triplets
- }
- if(bLast) // when the last line, the last pixel - colud be a problem if bitmap DWORD alligned
- for(int c=3;c;c--) *pcImgD++=*pcImgS++; // (only last three bytes available->could not read/write DWORD)!!
- else
- { ixHeight++;
- pcImgD+=nPadD; // destination bitmap horizontal padding to DWORD
- pcImgS=pcImg+(ixHeight*3); // reset the source to the begining of the next vertical line
- } }
- #else // __USE_MASM__
- nBmpWdtPS-=4; // adjust esi increment (due to esi self-incrementing by movsd)
- nWidth=szBmp.cx;
- __asm
- { mov esi, pcImg // source index
- mov edi, pcImgRotate // destination index
- xor ebx, ebx // vertical counter
- loop_height:
- mov ecx, nWidth // horizontal counter
- cmp ebx, nHeight1 // check is it the last line
- jne loop_width
- dec ecx // if it is decremnt for the last pixel
- loop_width:
- movsd // copies 4 bytes and increments source and destination by 4 (we need only 3 bytes copied 'one pixel' RGB triplet)
- dec edi // adjust edi to 'as incremented by 3'
- add esi,nBmpWdtPS // adjust esi to the next source line
- loop loop_width // loop one hotizontal destination line
- cmp ebx, nHeight1 // check is it the last line
- je do_last // if not last, do incrementing here
-
- inc ebx // increment vertical counter
- add edi, nPadD // adjust destination index by possible padding to DWORD
- mov esi, ebx // reset the source index: add vertical counter * 3
- shl esi, 1 // (is the same as * 2 +1*)
- add esi, ebx // +1*
- add esi, pcImg // add to the beginning of the source
- jmp loop_height // loop whole height
- do_last: // the last pixel is done by
- movsw // moving first two bytes
- movsb // and than by moving the very last byte
- }
- #endif // __USE_MASM__
- dcMem.SelectObject(pBmpOld); bmpMem.DeleteObject(); // recreate rotated bitmap
- bmpMem.CreateCompatibleBitmap(pDC,szBmp.cx,szBmp.cy);
- dcMem.SelectObject(&bmpMem);
- bihOut.biWidth =szBmp.cx; bihOut.biHeight=bBody?-szBmp.cy:szBmp.cy;
- SetDIBits(*pDC, bmpMem.operator HBITMAP(),0,szBmp.cy,pcImgRotate,&biOut,DIB_RGB_COLORS); // set rotated bitmap bits
- delete pcImgRotate;
- }
- if(pcImg) delete pcImg;
- // 6th blit mirrored/rotated image to the screen
- pDC->BitBlt(rcItem.left,rcItem.top,szBmp.cx,szBmp.cy,&dcMem,0,0,SRCCOPY); //
- dcMem.SelectObject(pBmpOld);
- CRect rc(100,0,1050,50);//85
- //pDC->FillSolidRect(rc, g_Color);
- }
- //----------------------------------------------------------------------------------------------------------
- // draw tab item context: possible icon and text
- void CTabSheet::DrawTabItem(CDC* pDC, int ixItem, const CRect& rcItemC, UINT uiFlags)
- {
- TC_ITEM tci; CString sText;
- tci.mask =TCIF_TEXT | TCIF_IMAGE;
- tci.pszText =sText.GetBuffer(128);
- tci.cchTextMax=127;
- GetItem(ixItem,&tci);
- sText.ReleaseBuffer();
- BOOL bSel =(uiFlags&2)?TRUE:FALSE;
- BOOL bBottom=(uiFlags&8)?TRUE:FALSE;
- CRect rcItem=rcItemC;
- if(bSel) rcItem.bottom -= 1;
- else rcItem.bottom += 2;
- rcItem.left+=(bBottom?3:6); // text & icon
- rcItem.top +=(bBottom?3:2) + (bSel ? 1 : (bBottom?0:3));
- int nOldMode=pDC->SetBkMode(TRANSPARENT);
- HIMAGELIST hilTabs = (HIMAGELIST)TabCtrl_GetImageList(GetSafeHwnd()); // icon
- if(hilTabs && tci.iImage>=0)
- { ImageList_Draw(hilTabs, tci.iImage, *pDC, rcItem.left+(bSel?2:0), rcItem.top+(bSel?0:-2), ILD_TRANSPARENT);
- rcItem.left+=19;
- }
- else rcItem.OffsetRect(-2,0);
- if(sText.GetLength())
- { CFont* pOldFont=pDC->SelectObject(GetFont()); // prepare dc
- rcItem.right-=3; // text
- CRect rect(0,0,rcItem.Width(),20);
- ::DrawText(pDC->GetSafeHdc(),sText.GetBuffer(sText.GetLength()+4),-1,rect,DT_CALCRECT|DT_SINGLELINE|DT_MODIFYSTRING|DT_END_ELLIPSIS);
- sText.ReleaseBuffer();
- rcItem.OffsetRect((bBottom?-1:0),(bSel?1:-1));
- pDC->DrawText(sText, rcItem, DT_NOPREFIX|DT_CENTER);
- pDC->SelectObject(pOldFont);
- }
- pDC->SetBkMode(nOldMode);
- }
- //----------------------------------------------------------------------------------------------------------
- //BOOL CXPTabCtrl::IsExtendedTabTheamedXP()
- //{
- // if(!m_bTabExtended || !::IsWindow(GetSafeHwnd()))
- // return FALSE;
- // DWORD dwStyle=GetStyle();
- // m_eTabOrientation=(dwStyle&TCS_BOTTOM)?e_tabBottom:e_tabTop;
- // if(dwStyle&TCS_VERTICAL)
- // m_eTabOrientation=(m_eTabOrientation==e_tabTop)?e_tabLeft:e_tabRight;
- //#ifdef USE_DEFAULT_XP_TOPTAB
- // if(m_eTabOrientation==e_tabTop) return FALSE;
- //#endif
- // return IsThemeActiveXP()?TRUE:FALSE;
- //}
- //==========================================================================================================
- //// these two messages are necessary only to properly redraw deselected tab background, because
- //void CTabSheet::OnTabSelChanging(NMHDR* pNMHDR, LRESULT* pResult) // selected rect was inflated by 2 points
- //{
- // UNUSED_ALWAYS(pNMHDR);
- // m_ixSelOld=GetCurSel();
- // *pResult=0L;
- //}
- //----------------------------------------------------------------------------------------------------------
- //void CTabSheet::OnTabSelChanged(NMHDR* pNMHDR, LRESULT* pResult)
- //{
- // UNUSED_ALWAYS(pNMHDR);
- // if(m_ixSelOld>=0 && m_ixSelOld!=GetCurSel() && IsExtendedTabTheamedXP()) // else
- // { CWnd* pWndParent=GetParent();
- // m_iNowSel = GetCurSel();
- // if(pWndParent)
- // { CRect rcOldSel; GetItemRect(m_ixSelOld, rcOldSel); rcOldSel.InflateRect(2,2);
- // ClientToScreen(&rcOldSel); pWndParent->ScreenToClient(&rcOldSel);
- // pWndParent->InvalidateRect(rcOldSel);
- // } }
- // *pResult=1L;
- //}
- /***********************************************************************************************************/
- // Helper functions
- /***********************************************************************************************************/
- int DWordAlign(int n)
- { const int rem=n%4; if(rem) n+=(4-rem); return n; }
- //----------------------------------------------------------------------------------------------------------
- BOOL IsThemeActiveEx()
- { // check theme activity always (could change during application running)
- HINSTANCE hDll=LoadLibrary(CString((LPCTSTR)IDS_UTIL_UXTHEME)); // 'UxTheme.dll'
- if(hDll==NULL) return FALSE; // the DLL won't be available on anything except Windows XP
- UINT (PASCAL *pfnIsThemeActive)();
- (FARPROC&)pfnIsThemeActive=GetProcAddress(hDll,CString((LPCTSTR)IDS_UTIL_THEMEACT)); // 'IsThemeActive'
- UINT uiThemeActive=0;
- if(pfnIsThemeActive)
- uiThemeActive=pfnIsThemeActive();
- FreeLibrary(hDll);
- return uiThemeActive?TRUE:FALSE;
- }
- //----------------------------------------------------------------------------------------------------------
- #define PACKVERSION(major,minor) MAKELONG(minor,major)
- DWORD GetWinVersion()
- {
- static DWORD c_dwWinVers=0; // check win version only once (will not change during application)
- if(!c_dwWinVers)
- { OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); // Initialize the OSVERSIONINFO structure.
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&osvi);
- c_dwWinVers=PACKVERSION(osvi.dwMajorVersion,osvi.dwMinorVersion);
- }
- return c_dwWinVers;
- }
- //----------------------------------------------------------------------------------------------------------
- BOOL IsWinXP() { return GetWinVersion()>=PACKVERSION(5,1)?TRUE:FALSE; }
- //----------------------------------------------------------------------------------------------------------
- BOOL IsThemeActiveXP() { return (IsWinXP() && IsThemeActiveEx())?TRUE:FALSE; }
- //----------------------------------------------------------------------------------------------------------
- #define WPART_NAME_SZ 128
- HRESULT DrawThemesPart(HDC hDC, int iPartId, int iStateId, LPCSTR uiPartNameID, LPRECT prcBox)
- {
- if(!IsWinXP()) return E_FAIL;
- HINSTANCE hDll=LoadLibrary(CString((LPCTSTR)IDS_UTIL_UXTHEME)); // 'UxTheme.dll'
- if(!hDll) return E_FAIL;
- BOOL (PASCAL* pfnIsThemeActive)(); UINT hTheme=0;
- (FARPROC&)pfnIsThemeActive=GetProcAddress(hDll,CString((LPCTSTR)IDS_UTIL_THEMEACT)); // 'IsThemeActive'
- HRESULT hResult=E_FAIL;
- if(pfnIsThemeActive && pfnIsThemeActive())
- { CString sPartName((LPCTSTR)uiPartNameID);
- if(sPartName.GetLength()>0)
- { WCHAR swPartName[WPART_NAME_SZ];
- MultiByteToWideChar(CP_ACP,0,(LPCSTR)sPartName,-1,swPartName,sizeof(swPartName)/sizeof(WCHAR));
- UINT (PASCAL* pfnOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
- (FARPROC&)pfnOpenThemeData=GetProcAddress(hDll,CString((LPCTSTR)IDS_UTIL_THEMEOPN));// 'OpenThemeData'
- if(pfnOpenThemeData && (hTheme=pfnOpenThemeData(NULL, swPartName))!=0)
- { UINT (PASCAL* pfnDrawThemeBackground)(UINT htheme,HDC hdc,int iPartID,int iStateID,const RECT* prcBx,const RECT* prcClip);
- (FARPROC&)pfnDrawThemeBackground=GetProcAddress(hDll,CString((LPCTSTR)IDS_UTIL_THEMEBCKG)); // 'DrawThemeBackground'
- if(pfnDrawThemeBackground)
- hResult=pfnDrawThemeBackground(hTheme, hDC, iPartId, iStateId, prcBox, NULL);
- } } }
- FreeLibrary(hDll);
- return hResult;
- }
|