PCONTROLDATA SkipControlData( PCONTROLDATA pcd) { BYTE UNALIGNED *pb; /* * Skip the fixed portion. */ pb = (PBYTE)pcd + SIZEOF_CONTROLDATA; /* * Skip the class. */ pb += NameOrdLen((LPTSTR)pb); /* * Skip the text. */ pb += NameOrdLen((LPTSTR)pb); /* * Finally, skip the Create Struct Data. * After this, pb will be pointing to the next control. */ pb += *(PWORD)pb + sizeof(WORD); DWordAlign(&pb); return (PCONTROLDATA)pb; }
PCONTROLDATA ParseDialogBoxHeader( PDIALOGBOXHEADER pdbh, PDWORD pflStyle, PDWORD pflExtStyle, PINT pcdit, PINT px, PINT py, PINT pcx, PINT pcy, LPTSTR *ppszMenuName, LPTSTR *ppszClass, LPTSTR *ppszCaption, PINT pPointSize, LPTSTR *ppszFontName) { BYTE UNALIGNED *pb; *pflStyle = pdbh->lStyle; *pflExtStyle = pdbh->lExtendedStyle; *pcdit = pdbh->NumberOfItems; *px = (SHORT)pdbh->x; *py = (SHORT)pdbh->y; *pcx = (SHORT)pdbh->cx; *pcy = (SHORT)pdbh->cy; pb = (PBYTE)pdbh + SIZEOF_DIALOGBOXHEADER; *ppszMenuName = (LPTSTR)pb; pb += NameOrdLen((LPTSTR)pb); *ppszClass = (LPTSTR)pb; pb += NameOrdLen((LPTSTR)pb); *ppszCaption = (LPTSTR)pb; pb += (lstrlen((LPTSTR)pb) + 1) * sizeof(TCHAR); /* * Does the template specify a font? */ if (pdbh->lStyle & DS_SETFONT) { *pPointSize = (SHORT)(*(PWORD)pb); pb += sizeof(WORD); *ppszFontName = (LPTSTR)pb; pb += (lstrlen((LPTSTR)pb) + 1) * sizeof(TCHAR); } else { *pPointSize = 0; *ppszFontName = NULL; } DWordAlign(&pb); return (PCONTROLDATA)pb; }
static CONTROLITEM *ParseDialogBoxHeader(PDIALOGBOXHEADER pdbh, int exStyle) { CLASSTEMPLATE *ct; BYTE *pb; DWORD style,ExtStyle; char *MenuName,*Class,*Caption,*FontName,AsciiCaption[512]; int PointSize; if (exStyle) { style = pdbh->lExtendedStyle; ExtStyle = pdbh->lStyle; } else { style = pdbh->lStyle; ExtStyle = pdbh->lExtendedStyle; } printf("Style 0x%x, Extended style 0x%x\nNumber of items %d. ",style,ExtStyle,pdbh->NumberOfItems); printf("Coords: x = %d, y = %d, cx = %d, cy = %d\n",pdbh->x, pdbh->y, pdbh->cx, pdbh->cy); pb = (char *) pdbh + SIZEOF_DIALOGBOXHEADER; MenuName = (LPTSTR) pb; pb += NameOrdLenW((LPTSTR) pb); Class = (LPTSTR) pb; ct = (CLASSTEMPLATE *)pb; if (ct->Scheme == RCH_ORDINAL_SCHEME || ct->Scheme == 0xFFFF0000) { pb += sizeof(CLASSTEMPLATE); } else { pb += NameOrdLenW((LPTSTR) pb); } Caption = (LPTSTR) pb; ConvertWideString(Caption,AsciiCaption); printf("Caption: \"%s\"\n",AsciiCaption); pb += (wcslen((LPWSTR) pb) + 1) * sizeof(WCHAR); /* Does the template specify a font? */ if (style & DS_SETFONT) { PointSize = (SHORT) (*(WORD *) pb); pb += sizeof(WORD); if (*((unsigned short *)pb) == 0) pb += 4; FontName = (LPTSTR) pb; ConvertWideString(FontName,AsciiCaption); printf("Font \"%s\" %d\n",AsciiCaption,PointSize); pb += (wcslen((LPWSTR) pb) + 1) * sizeof(WCHAR); } else { PointSize = 0; FontName = NULL; } DWordAlign((PBYTE *)&pb); return (CONTROLITEM *) pb; }
static CONTROLITEM *ParseControlData(CONTROLITEM * pcd, int fextStyle) { char *pb,*Class,*Text,Ascii[250]; CLASSTEMPLATE *lpvdict; int Style,ExtStyle; if (fextStyle) { pcd = (CONTROLITEM *)((PBYTE)pcd + 4); Style = pcd->lExtendedStyle; ExtStyle = pcd->Style; } else { Style = pcd->Style; ExtStyle = pcd->lExtendedStyle; } printf("Control Id = %d\n",pcd->ID); printf("Style= 0x%x, extended style 0x%x. Coords: x=%d, y=%d, cx=%d, cy=%d\n", Style,ExtStyle,pcd->x,pcd->y,pcd->cx,pcd->cy); pb = (PBYTE)pcd + SIZEOF_CONTROLITEM; Class = (LPTSTR)pb; lpvdict = (CLASSTEMPLATE *)pb; if (lpvdict->Scheme == RCH_ORDINAL_SCHEME || lpvdict->Scheme == 0xFFFF0000) { pb += sizeof(CLASSTEMPLATE); } else { if (pb[0] == 0 && pb[1] == 0) pb += 2; Class = (LPTSTR)pb; pb += NameOrdLenW((LPTSTR)pb); } Text = (LPTSTR)pb; ConvertWideString(Text,Ascii); printf("Text \"%s\"\n",Ascii); if (IsOrd(Class)) printf("Class = 0x%x\n",OrdID(Class)); else { printf("Class = 0x%d\n",*Class); } pb += NameOrdLenW((LPTSTR)pb); /* * Finally, skip the Create Struct Data. * After this, pb will be pointing to the next control. */ pb += *(PWORD)pb + sizeof(WORD); DWordAlign((PBYTE *)&pb); return (CONTROLITEM *)pb; }
PCONTROLDATA ParseControlData( PCONTROLDATA pcd, PDWORD pflStyle, PDWORD pflExtStyle, PINT px, PINT py, PINT pcx, PINT pcy, PINT pid, LPTSTR *ppszClass, LPTSTR *ppszText) { BYTE UNALIGNED *pb; *pflStyle = pcd->lStyle; *pflExtStyle = pcd->lExtendedStyle; *px = (SHORT)pcd->x; *py = (SHORT)pcd->y; *pcx = (SHORT)pcd->cx; *pcy = (SHORT)pcd->cy; *pid = (SHORT)pcd->wId; pb = (PBYTE)pcd + SIZEOF_CONTROLDATA; *ppszClass = (LPTSTR)pb; pb += NameOrdLen((LPTSTR)pb); *ppszText = (LPTSTR)pb; pb += NameOrdLen((LPTSTR)pb); /* * Finally, skip the Create Struct Data. * After this, pb will be pointing to the next control. */ pb += *(PWORD)pb + sizeof(WORD); DWordAlign(&pb); return (PCONTROLDATA)pb; }
static PRES2 ResourcePart2(PRES pRes) { PBYTE pb; /* * Skip past the first part of the resource header. */ pb = (PBYTE)pRes + sizeof(RES); /* * Skip past the "Type" field to the name. */ pb = SkipSz((LPTSTR)pb); /* * Skip past the name field also. */ pb = SkipSz((LPTSTR)pb); DWordAlign(&pb); return (PRES2)pb; }
PCONTROLDATA SkipDialogBoxHeader( PDIALOGBOXHEADER pdbh) { BYTE UNALIGNED *pb; /* * Skip the fixed portion. */ pb = (PBYTE)pdbh + SIZEOF_DIALOGBOXHEADER; /* * Skip the menu. */ pb += NameOrdLen((LPTSTR)pb); /* * Skip the class. */ pb += NameOrdLen((LPTSTR)pb); /* * Skip the caption. */ pb += (lstrlen((LPTSTR)pb) + 1) * sizeof(TCHAR); /* * Does the template specify a font? */ if (pdbh->lStyle & DS_SETFONT) { pb += sizeof(WORD); pb += (lstrlen((LPTSTR)pb) + 1) * sizeof(TCHAR); } DWordAlign(&pb); return (PCONTROLDATA)pb; }
static HWND SearchResource(LPCSTR lpName, int type, DLGPROC pDialogProc, LPARAM param, char *lpFileBase, int TotalFileSize, HWND parentWnd) { char *pResAll = lpFileBase + TotalFileSize; PRES pRes = (PRES)lpFileBase; char pszSearchedName[256]; char *pszType = ResourceType(pRes); char *pszName; int size = ResourceSize(pRes); char Name[512],*bb; PDIALOGBOXHEADER pdbh; HWND result; UINT_PTR ul; ul = (UINT_PTR)lpName; if (HIWORD(ul) == 0) { sprintf(pszSearchedName,"%d",LOWORD(ul)); } else if (IsOrd((char *)lpName)) { sprintf(pszSearchedName,"%d",OrdID(lpName)); } else if (lpName[1] == 0 && lpName[3] == 0) { ConvertWideString((char *)lpName,(char *)pszSearchedName); } else { strcpy(pszSearchedName,lpName); } do { if (pRes->HeaderSize+pRes->DataSize == 0) break; if (IsOrd((char *)pRes) && OrdID(pRes) == ORDID_RT_DLGINCLUDE) { /* Ignore include files */ ; } else if (IsOrd((char *)pRes) && OrdID(pRes) == ORDID_RT_RESOURCE32) { /* * This is the dummy resource that identifies a * 32 bit resource file. This resource should be * skipped also. */ } else { /* This is some other kind of a resource. See if it matches */ if (pRes->DataSize) { int size = ResourceSize(pRes); pszType = ResourceType(pRes); if (IsOrd(pszType) && OrdID(pszType) == type) { pszName = ResourceName(pRes); if (!IsOrd(pszName)) { if (pszName[1] == 0 && pszName[3] == 0) ConvertWideString(pszName,Name); else strcpy(Name,pszName); } else { sprintf(Name,"%d",OrdID(pszName)); } if (!strcmp(Name,pszSearchedName)) { /* found it.*/ if (type == 5) { /* Build a dialog box */ pdbh = (PDIALOGBOXHEADER) SkipResHeader(pRes); bb = malloc(size); memcpy(bb,pdbh,size); result = CreateDialogIndirectParam(GetModuleHandle(NULL), (LPDLGTEMPLATE)bb, parentWnd, pDialogProc,param); free(bb); return result; } else if (type == 4) { /* Build a menu */ return (HWND) ReadMenu((char *)SkipResHeader(pRes)); } else if (type == 3) { /* Build an Icon */ HICON hicon; hicon = CreateIconFromResource((PBYTE)SkipResHeader(pRes), size, TRUE, 0x30000); return (HWND)hicon; } else if (type == 1) { /* Build a cursor */ return (HWND)CreateIconFromResource((PBYTE)SkipResHeader(pRes), size, FALSE, 0x30000); } else if (type == 2 || type == 14) { /* Build bitmap */ char *start = SkipResHeader(pRes); bb = malloc(size); memcpy(bb,start,size); return (HWND) bb; } } } } } /* Move to the next resource. */ pRes = (PRES) (((char *) pRes) + pRes->HeaderSize + pRes->DataSize); DWordAlign((PBYTE *)&pRes); } while (pRes < (PRES) ((char *) pResAll + size)); return (HWND) 0; }
//---------------------------------------------------------------------------------------------------------- // This function draws Themes Tab control parts: a) Tab-Body and b) Tab-tabs void CXPTabCtrl::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 #if !defined(_AMD64_) #define __USE_MASM__ // the same processing is in C and in asm. To use C -> comment the beginning of this line #endif // 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); }