Post a7448
- Poster: Anonymous
- Date: July 23 2010
- Size: 12288 bytes
- Syntax:
- Show/Hide Posting Box
- View Raw Post
windowFunctions.cpp (DCX)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | /*! * \file windowFunctions.cpp * \brief Methods related to manipulation of windows or information retrieval. * * This file contains the informative (debug/error/status) information for DCX dll routines. * * \author William Nguyen ( twig at genscripts dot net ) * \version 1.0 * * \b Revisions * * © ScriptsDB.org - 2007-2008 */ #include "defines.h" #include "Dcx.h" /*! * \brief Finds an owner of a dialog, used with styles. * * Returns the owner HWND */ HWND FindOwner(const TString & data, const HWND defaultWnd) { int i = data.findtok("owner", 1); // 'owner' token not found in data if (!i) return defaultWnd; // if there is a token after 'owner' if (i < data.numtok( )) { // if it is a number (HWND) passed HWND wnd = (HWND) data.gettok( i +1 ).to_num(); if (wnd) return wnd; // try to retrieve dialog hwnd from name wnd = GetHwndFromString(data.gettok( i +1 )); if (wnd) return wnd; } return defaultWnd; } /*! * \brief Retrieves a HWND from the string. */ HWND GetHwndFromString(const TString &str) { return GetHwndFromString(str.to_chr()); } /*! * \brief Retireves a HWND from the string. */ HWND GetHwndFromString(const char *str) { // test code to allow docking by hwnd (wtf its only 3 lines) HWND hwnd = (HWND)_atoi64(str); if (IsWindow(hwnd)) return hwnd; char res[20]; Dcx::mIRC.evalex( res, 20, "$dialog(%s).hwnd", str); return (HWND) atol(res); } // Removes window style to a window void RemStyles(HWND hwnd,int parm,long RemStyles) { DWORD Styles = (DWORD)GetWindowLong(hwnd, parm); Styles &= ~RemStyles; SetWindowLong(hwnd, parm, Styles); } // Adds window styles to a window void AddStyles(HWND hwnd,int parm,long AddStyles) { DWORD Styles = (DWORD)GetWindowLong(hwnd, parm); Styles |= AddStyles; SetWindowLong(hwnd, parm, Styles); } /***************************************************/ /* David Gallardo Llopis */ /* */ /* Based on the code in the book */ /* PROGRAMACION AVANZADA EN WINDOWS 2000 */ /* at McGraw-Hill (c) 2000 */ /* by */ /* J. Pascual, F. Charte, M.J. Segarra, */ /* J.A. Clavijo, A. de Antonio. */ /* */ /* The code in this book is based on an original */ /* code by Jean-Edouard Lachand-Robert */ /***************************************************/ HRGN BitmapRegion(HBITMAP hBitmap,COLORREF cTransparentColor,BOOL bIsTransparent) { // We create an empty region HRGN hRegion=NULL; // If the passed bitmap is NULL, go away! if(hBitmap == NULL) return NULL; // We create a memory context for working with the bitmap // The memory context is compatible with the display context (screen) HDC hMemDC = CreateCompatibleDC(NULL); // If no context is created, go away, too! if(hMemDC == NULL) return NULL; // Computation of the bitmap size BITMAP bmBitmap; GetObject(hBitmap, sizeof(bmBitmap), &bmBitmap); // In order to make the space for the region, we // create a bitmap with 32bit depth color and with the // size of the loaded bitmap! //BITMAPINFOHEADER RGB32BITSBITMAPINFO= //{ // sizeof(BITMAPINFOHEADER), // bmBitmap.bmWidth, // bmBitmap.bmHeight, // 1,32,BI_RGB,0,0,0,0,0 //}; BITMAPINFO RGB32BITSBITMAPINFO = { sizeof(BITMAPINFOHEADER), bmBitmap.bmWidth, bmBitmap.bmHeight, 1,32,BI_RGB,0,0,0,0,0,0 }; // Here is the pointer to the bitmap data VOID *pBits; // With the previous information, we create the new bitmap! HBITMAP hNewBitmap; hNewBitmap = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pBits, NULL, 0); // If the creation process succeded... if(hNewBitmap != NULL) { GdiFlush(); // We select the bitmap onto the created memory context // and then we store the previosly selected bitmap on this context! HBITMAP hPrevBmp=(HBITMAP) SelectObject(hMemDC,hNewBitmap); // We create another device context compatible with the first! HDC hDC=CreateCompatibleDC(hMemDC); // If success... if(hDC != NULL) { // We compute the number of bytes per row that the bitmap contains, rounding to 32 bit-multiples BITMAP bmNewBitmap; GetObject(hNewBitmap,sizeof(bmNewBitmap),&bmNewBitmap); while(bmNewBitmap.bmWidthBytes % 4) bmNewBitmap.bmWidthBytes++; // Copy of the original bitmap on the memory context! HBITMAP hPrevBmpOrg=(HBITMAP) SelectObject(hDC,hBitmap); BitBlt(hMemDC,0,0,bmBitmap.bmWidth,bmBitmap.bmHeight,hDC,0,0,SRCCOPY); // In order to optimize the code, we don't call the GDI each time we // find a transparent pixel. We use a RGN_DATA structure were we store // consecutive rectangles, until we have a large amount of them and then we crete // the composed region with ExtCreateRgn(), combining it with the main region. // Then we begin again initializing the RGN_DATA structure and doing another // iteration, until the entire bitmap is analyzed. // Also, in order to not saturate the Windows API with calls for reserving // memory, we wait until NUMRECT rectangles are stores in order to claim // for another NUMRECT memory space! #define NUMRECT 100 DWORD maxRect = NUMRECT; // We create the memory data HANDLE hData=GlobalAlloc(GMEM_MOVEABLE,sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRect)); RGNDATA *pData=(RGNDATA*) GlobalLock(hData); pData->rdh.dwSize=sizeof(RGNDATAHEADER); pData->rdh.iType=RDH_RECTANGLES; pData->rdh.nCount=pData->rdh.nRgnSize=0; SetRect(&pData->rdh.rcBound,MAXLONG,MAXLONG,0,0); // We study each pixel on the bitmap... BYTE *Pixeles=(BYTE*) bmNewBitmap.bmBits+(bmNewBitmap.bmHeight-1)*bmNewBitmap.bmWidthBytes; // Main loop for(int Row=0;Row<bmBitmap.bmHeight;Row++) { // Horizontal loop for(int Column=0;Column<bmBitmap.bmWidth;Column++) { // We optimized searching for adjacent transparent pixels! int Xo=Column; RGBQUAD *Pixel=(RGBQUAD*) Pixeles+Column; while(Column<bmBitmap.bmWidth) { BOOL bInRange=FALSE; // If the color is that indicated as transparent... if( Pixel->rgbRed==GetRValue(cTransparentColor) && Pixel->rgbGreen==GetGValue((cTransparentColor & 0xFFFF)) && Pixel->rgbBlue==GetBValue(cTransparentColor) ) bInRange=TRUE; if((bIsTransparent) && (bInRange)) break; if((!bIsTransparent) && (!bInRange)) break; Pixel++; Column++; } // while (Column < bm.bmWidth) if(Column>Xo) { // We add the rectangle (Xo,Row),(Column,Row+1) to the region // If the number of rectangles is greater then NUMRECT, we claim // another pack of NUMRECT memory places! if (pData->rdh.nCount>=maxRect) { GlobalUnlock(hData); maxRect+=NUMRECT; hData=GlobalReAlloc(hData,sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRect),GMEM_MOVEABLE); pData=(RGNDATA *)GlobalLock(hData); } RECT *pRect=(RECT*) &pData->Buffer; SetRect(&pRect[pData->rdh.nCount],Xo,Row,Column,Row+1); if(Xo<pData->rdh.rcBound.left) pData->rdh.rcBound.left=Xo; if(Row<pData->rdh.rcBound.top) pData->rdh.rcBound.top=Row; if(Column>pData->rdh.rcBound.right) pData->rdh.rcBound.right=Column; if(Row+1>pData->rdh.rcBound.bottom) pData->rdh.rcBound.bottom=Row+1; pData->rdh.nCount++; // In Win95/08 there is a limitation on the maximum number of // rectangles a RGN_DATA can store (aprox. 4500), so we call // the API for a creation and combination with the main region // each 2000 rectangles. This is a good optimization, because // instead of calling the routines for combining for each new // rectangle found, we call them every 2000 rectangles!!! if(pData->rdh.nCount==2000) { HRGN hNewRegion=ExtCreateRegion(NULL,sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRect),pData); if (hNewRegion != NULL) { // Si ya existe la región principal,sumamos la nueva, // si no,entonces de momento la principal coincide con // la nueva región. if (hRegion) { CombineRgn(hRegion,hRegion,hNewRegion,RGN_OR); DeleteObject(hNewRegion); } else hRegion=hNewRegion; } // Volvemos a comenzar la suma de rectángulos pData->rdh.nCount=0; SetRect(&pData->rdh.rcBound,MAXLONG,MAXLONG,0,0); } } // if (Column > Xo) } // for (int Column ...) // Nueva Row. Lo del negativo se debe a que el bitmap está invertido // verticalmente. Pixeles -= bmNewBitmap.bmWidthBytes; } // for (int Row...) if (pData->rdh.nCount > 0) { // Una vez finalizado el proceso,procedemos a la fusión de la // región remanente desde la última fusión hasta el final HRGN hNewRegion=ExtCreateRegion(NULL,sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRect),pData); if(hNewRegion != NULL) { // If the main region does already exist, we add the new one, if(hRegion) { CombineRgn(hRegion,hRegion,hNewRegion,RGN_OR); DeleteObject(hNewRegion); } else // if not, we consider the new one to be the main region at first! hRegion=hNewRegion; } } // We free the allocated memory and the rest of used ressources GlobalUnlock(hData); GlobalFree(hData); SelectObject(hDC,hPrevBmpOrg); // don't del prev bitmap, as its our supplied one. DeleteDC(hDC); }// if (hDC) DeleteBitmap(SelectObject(hMemDC,hPrevBmp)); // del prev bitmap as it's the DIB Section } //if (hNewBitmap) else { //DWORD err = GetLastError(); // Only ever returns `Invalid Parameters` Dcx::error("BitmapRegion()","CreateDIBSection() Failed: Invalid Parameter"); } DeleteDC(hMemDC); return hRegion; } /*! * \brief Changes the icon for a window. * * Returns true if successful. */ bool ChangeHwndIcon(const HWND hwnd, const TString &flags, const int index, TString &filename) { filename.trim(); if (const_cast<TString &>(flags)[0] != '+') { Dcx::error("ChangeHwndIcon", "Invalid Flags"); return false; } if (!IsFile(filename)) { Dcx::errorex("ChangeHwndIcon", "Unable to Access File: %s", filename.to_chr()); return false; } HICON iconSmall = NULL; HICON iconLarge = NULL; // check for +s small icon flag bool doSmall = (flags.find('s',0) ? true : false); // check for +b big icon flag bool doBig = (flags.find('b',0) ? true : false); if (doSmall || doBig) { // doing big &/or small icon if (doSmall) iconSmall = dcxLoadIcon(index, filename, false, flags); if (doBig) iconLarge = dcxLoadIcon(index, filename, true, flags); } else { // No big or small flags, so do both icons. iconSmall = dcxLoadIcon(index, filename, false, flags); iconLarge = dcxLoadIcon(index, filename, true, flags); } if ((iconLarge == NULL) && (iconSmall == NULL)) { Dcx::error("ChangeHwndIcon", "Error Extracting Icon"); return false; } // set the new icons, get back the current icon if (iconSmall != NULL) iconSmall = (HICON) SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) iconSmall); if (iconLarge != NULL) iconLarge = (HICON) SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) iconLarge); // delete the old icons if (iconSmall != NULL) DestroyIcon(iconSmall); if ((iconLarge != NULL) && (iconSmall != iconLarge)) // dont delete twice DestroyIcon(iconLarge); //UINT cnt = 0; //if (flags.find('a',0)) { // WORD wIndex = index; // iconLarge = ExtractAssociatedIcon(GetModuleHandle(NULL), filename.to_chr(), &wIndex); // cnt++; //} //else { // cnt = ExtractIconEx(filename.to_chr(), index, NULL, &iconSmall, 1); // cnt += ExtractIconEx(filename.to_chr(), index, &iconLarge, NULL, 1); //} //// NB: shouldnt this be CopyIcon() ? //// copy the icon over in case there was no small icon //if (!iconLarge) // iconLarge = iconSmall; //// copy the icon over in case there was no large icon //if (!iconSmall) // iconSmall = iconLarge; //// TODO: add more meaningful error messages //// No icon in file //if (cnt == 0) { // DCXError("ChangeHwndIcon", "No icon in file"); // return false; //} //if (!iconLarge && !iconSmall) { // DCXError("ChangeHwndIcon", "Error Extracting Icon"); // return false; //} //if (flags.find('g', 0)) { // iconSmall = CreateGrayscaleIcon(iconSmall); // if (iconSmall != iconLarge) // no need to convert twice. // iconLarge = CreateGrayscaleIcon(iconLarge); //} //// set the new icons, get back the current icon //iconSmall = (HICON) SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) iconSmall); //iconLarge = (HICON) SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) iconLarge); //// delete the old icons //if (iconSmall) // DestroyIcon(iconSmall); //if (iconLarge && (iconSmall != iconLarge)) // dont delete twice // DestroyIcon(iconLarge); return true; } |