Changeset 6709 for trunk/src/comctl32
- Timestamp:
- Sep 15, 2001, 11:26:26 AM (24 years ago)
- Location:
- trunk/src/comctl32
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/comctl32/animate.c
r6705 r6709 4 4 * 5 5 * Copyright 1998, 1999 Eric Kohl 6 * 6 * 1999 Eric Pouech 7 7 * 8 8 * NOTES … … 33 33 #endif 34 34 /* reference to input stream (file or resource) */ 35 HGLOBAL 36 HMMIO hMMio;/* handle to mmio stream */37 HWND 35 HGLOBAL hRes; 36 HMMIO hMMio; /* handle to mmio stream */ 37 HWND hWnd; 38 38 /* information on the loaded AVI file */ 39 MainAVIHeader 40 AVIStreamHeader 41 LPBITMAPINFOHEADER 42 LPDWORD 39 MainAVIHeader mah; 40 AVIStreamHeader ash; 41 LPBITMAPINFOHEADER inbih; 42 LPDWORD lpIndex; 43 43 /* data for the decompressor */ 44 HIC 45 LPBITMAPINFOHEADER 46 LPVOID 47 LPVOID 44 HIC hic; 45 LPBITMAPINFOHEADER outbih; 46 LPVOID indata; 47 LPVOID outdata; 48 48 /* data for the background mechanism */ 49 CRITICAL_SECTION 50 HANDLE 51 UINT 49 CRITICAL_SECTION cs; 50 HANDLE hThread; 51 UINT uTimer; 52 52 /* data for playing the file */ 53 int 54 int 55 int 56 int 53 int nFromFrame; 54 int nToFrame; 55 int nLoop; 56 int currFrame; 57 57 /* tranparency info*/ 58 COLORREF transparentColor;59 HBRUSH 60 HBITMAP 58 COLORREF transparentColor; 59 HBRUSH hbrushBG; 60 HBITMAP hbmPrevFrame; 61 61 } ANIMATE_INFO; 62 62 63 63 #define ANIMATE_GetInfoPtr(hWnd) ((ANIMATE_INFO *)GetWindowLongA(hWnd, 0)) 64 #define ANIMATE_COLOR_NONE 64 #define ANIMATE_COLOR_NONE 0xffffffff 65 65 66 66 static void ANIMATE_Notify(ANIMATE_INFO* infoPtr, UINT notif) 67 67 { 68 SendMessageA(GetParent(infoPtr->hWnd), WM_COMMAND, 69 MAKEWPARAM(GetDlgCtrlID(infoPtr->hWnd), notif), 70 68 SendMessageA(GetParent(infoPtr->hWnd), WM_COMMAND, 69 MAKEWPARAM(GetDlgCtrlID(infoPtr->hWnd), notif), 70 (LPARAM)infoPtr->hWnd); 71 71 } 72 72 … … 77 77 #endif 78 78 { 79 HRSRC 80 MMIOINFO 81 LPVOID 82 79 HRSRC hrsrc; 80 MMIOINFO mminfo; 81 LPVOID lpAvi; 82 83 83 #ifdef __WIN32OS2__ 84 84 if (unicode) … … 90 90 #endif 91 91 if (!hrsrc) 92 93 92 return FALSE; 93 94 94 infoPtr->hRes = LoadResource(hInst, hrsrc); 95 95 if (!infoPtr->hRes) 96 97 96 return FALSE; 97 98 98 lpAvi = LockResource(infoPtr->hRes); 99 99 if (!lpAvi) 100 101 100 return FALSE; 101 102 102 memset(&mminfo, 0, sizeof(mminfo)); 103 103 mminfo.fccIOProc = FOURCC_MEM; … … 106 106 infoPtr->hMMio = mmioOpenA(NULL, &mminfo, MMIO_READ); 107 107 if (!infoPtr->hMMio) { 108 109 108 GlobalFree((HGLOBAL)lpAvi); 109 return FALSE; 110 110 } 111 111 … … 127 127 #else 128 128 infoPtr->hMMio = mmioOpenA((LPSTR)lpName, NULL, 129 129 MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE); 130 130 #endif 131 131 if (!infoPtr->hMMio) 132 133 132 return FALSE; 133 134 134 return TRUE; 135 135 } … … 141 141 142 142 /* should stop playing */ 143 if (infoPtr->hThread) 143 if (infoPtr->hThread) 144 144 { 145 145 if (!TerminateThread(infoPtr->hThread,0)) 146 146 WARN("could not destroy animation thread!\n"); 147 147 infoPtr->hThread = 0; 148 148 } 149 149 if (infoPtr->uTimer) { 150 151 150 KillTimer(infoPtr->hWnd, infoPtr->uTimer); 151 infoPtr->uTimer = 0; 152 152 } 153 153 … … 163 163 { 164 164 if (infoPtr->hMMio) { 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 165 ANIMATE_DoStop(infoPtr); 166 mmioClose(infoPtr->hMMio, 0); 167 if (infoPtr->hRes) { 168 FreeResource(infoPtr->hRes); 169 infoPtr->hRes = 0; 170 } 171 if (infoPtr->lpIndex) { 172 HeapFree(GetProcessHeap(), 0, infoPtr->lpIndex); 173 infoPtr->lpIndex = NULL; 174 } 175 if (infoPtr->hic) { 176 ICClose(infoPtr->hic); 177 infoPtr->hic = 0; 178 } 179 if (infoPtr->inbih) { 180 HeapFree(GetProcessHeap(), 0, infoPtr->inbih); 181 infoPtr->inbih = NULL; 182 } 183 if (infoPtr->outbih) { 184 HeapFree(GetProcessHeap(), 0, infoPtr->outbih); 185 infoPtr->outbih = NULL; 186 } 187 187 if( infoPtr->indata ) 188 188 { 189 189 HeapFree(GetProcessHeap(), 0, infoPtr->indata); 190 190 infoPtr->indata = NULL; 191 191 } 192 192 if( infoPtr->outdata ) 193 193 { 194 194 HeapFree(GetProcessHeap(), 0, infoPtr->outdata); 195 195 infoPtr->outdata = NULL; 196 196 } 197 197 if( infoPtr->hbmPrevFrame ) 198 198 { 199 199 DeleteObject(infoPtr->hbmPrevFrame); 200 200 infoPtr->hbmPrevFrame = 0; 201 201 } 202 203 204 205 206 207 208 209 } 210 infoPtr->transparentColor = ANIMATE_COLOR_NONE; 202 infoPtr->indata = infoPtr->outdata = NULL; 203 infoPtr->hWnd = 0; 204 infoPtr->hMMio = 0; 205 206 memset(&infoPtr->mah, 0, sizeof(infoPtr->mah)); 207 memset(&infoPtr->ash, 0, sizeof(infoPtr->ash)); 208 infoPtr->nFromFrame = infoPtr->nToFrame = infoPtr->nLoop = infoPtr->currFrame = 0; 209 } 210 infoPtr->transparentColor = ANIMATE_COLOR_NONE; 211 211 } 212 212 213 213 static void ANIMATE_TransparentBlt(ANIMATE_INFO* infoPtr, HDC hdcDest, HDC hdcSource) 214 { 214 { 215 215 HDC hdcMask; 216 216 HBITMAP hbmMask; 217 HBITMAP hbmOld; 218 217 HBITMAP hbmOld; 218 219 219 /* create a transparency mask */ 220 220 hdcMask = CreateCompatibleDC(hdcDest); 221 hbmMask = CreateBitmap(infoPtr->inbih->biWidth, infoPtr->inbih->biHeight, 1,1,NULL); 222 hbmOld = SelectObject(hdcMask, hbmMask); 221 hbmMask = CreateBitmap(infoPtr->inbih->biWidth, infoPtr->inbih->biHeight, 1,1,NULL); 222 hbmOld = SelectObject(hdcMask, hbmMask); 223 223 224 224 SetBkColor(hdcSource,infoPtr->transparentColor); 225 225 BitBlt(hdcMask,0,0,infoPtr->inbih->biWidth, infoPtr->inbih->biHeight,hdcSource,0,0,SRCCOPY); 226 226 227 227 /* mask the source bitmap */ 228 SetBkColor(hdcSource, RGB(0,0,0)); 229 SetTextColor(hdcSource, RGB(255,255,255)); 228 SetBkColor(hdcSource, RGB(0,0,0)); 229 SetTextColor(hdcSource, RGB(255,255,255)); 230 230 BitBlt(hdcSource, 0, 0, infoPtr->inbih->biWidth, infoPtr->inbih->biHeight, hdcMask, 0, 0, SRCAND); 231 231 232 232 /* mask the destination bitmap */ 233 SetBkColor(hdcDest, RGB(255,255,255)); 234 SetTextColor(hdcDest, RGB(0,0,0)); 233 SetBkColor(hdcDest, RGB(255,255,255)); 234 SetTextColor(hdcDest, RGB(0,0,0)); 235 235 BitBlt(hdcDest, 0, 0, infoPtr->inbih->biWidth, infoPtr->inbih->biHeight, hdcMask, 0, 0, SRCAND); 236 236 … … 258 258 259 259 if (!hDC || !infoPtr->inbih) 260 260 return TRUE; 261 261 262 262 if (infoPtr->hic ) … … 266 266 267 267 nWidth = infoPtr->outbih->biWidth; 268 nHeight = infoPtr->outbih->biHeight; 268 nHeight = infoPtr->outbih->biHeight; 269 269 } else 270 { 270 { 271 271 pBitmapData = infoPtr->indata; 272 272 pBitmapInfo = (LPBITMAPINFO)infoPtr->inbih; 273 273 274 274 nWidth = infoPtr->inbih->biWidth; 275 nHeight = infoPtr->inbih->biHeight; 276 } 275 nHeight = infoPtr->inbih->biHeight; 276 } 277 277 278 278 if(!infoPtr->hbmPrevFrame) … … 281 281 } 282 282 283 SetDIBits(hDC, infoPtr->hbmPrevFrame, 0, nHeight, pBitmapData, (LPBITMAPINFO)pBitmapInfo, DIB_RGB_COLORS); 284 283 SetDIBits(hDC, infoPtr->hbmPrevFrame, 0, nHeight, pBitmapData, (LPBITMAPINFO)pBitmapInfo, DIB_RGB_COLORS); 284 285 285 hdcMem = CreateCompatibleDC(hDC); 286 286 hbmOld = SelectObject(hdcMem, infoPtr->hbmPrevFrame); 287 287 288 /* 289 * we need to get the transparent color even without ACS_TRANSPARENT, 288 /* 289 * we need to get the transparent color even without ACS_TRANSPARENT, 290 290 * because the style can be changed later on and the color should always 291 * be obtained in the first frame 291 * be obtained in the first frame 292 292 */ 293 293 if(infoPtr->transparentColor == ANIMATE_COLOR_NONE) 294 294 { 295 295 infoPtr->transparentColor = GetPixel(hdcMem,0,0); 296 } 297 298 if(GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_TRANSPARENT) 299 { 296 } 297 298 if(GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_TRANSPARENT) 299 { 300 300 HDC hdcFinal = CreateCompatibleDC(hDC); 301 301 HBITMAP hbmFinal = CreateCompatibleBitmap(hDC,nWidth, nHeight); 302 302 HBITMAP hbmOld2 = SelectObject(hdcFinal, hbmFinal); 303 303 RECT rect; 304 304 305 305 rect.left = 0; 306 306 rect.top = 0; 307 307 rect.right = nWidth; 308 308 rect.bottom = nHeight; 309 309 310 310 if(!infoPtr->hbrushBG) 311 311 infoPtr->hbrushBG = GetCurrentObject(hDC, OBJ_BRUSH); … … 320 320 infoPtr->hbmPrevFrame = hbmFinal; 321 321 } 322 323 if (GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_CENTER) 322 323 if (GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_CENTER) 324 324 { 325 RECT rect; 325 RECT rect; 326 326 327 327 GetWindowRect(infoPtr->hWnd, &rect); 328 nOffsetX = ((rect.right - rect.left) - nWidth)/2; 329 nOffsetY = ((rect.bottom - rect.top) - nHeight)/2; 330 } 331 BitBlt(hDC, nOffsetX, nOffsetY, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY); 328 nOffsetX = ((rect.right - rect.left) - nWidth)/2; 329 nOffsetY = ((rect.bottom - rect.top) - nHeight)/2; 330 } 331 BitBlt(hDC, nOffsetX, nOffsetY, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY); 332 332 333 333 SelectObject(hdcMem, hbmOld); … … 338 338 static LRESULT ANIMATE_DrawFrame(ANIMATE_INFO* infoPtr) 339 339 { 340 HDC 340 HDC hDC; 341 341 342 342 TRACE("Drawing frame %d (loop %d)\n", infoPtr->currFrame, infoPtr->nLoop); … … 346 346 mmioSeek(infoPtr->hMMio, infoPtr->lpIndex[infoPtr->currFrame], SEEK_SET); 347 347 mmioRead(infoPtr->hMMio, infoPtr->indata, infoPtr->ash.dwSuggestedBufferSize); 348 348 349 349 if (infoPtr->hic && 350 ICDecompress(infoPtr->hic, 0, infoPtr->inbih, infoPtr->indata, 351 infoPtr->outbih, infoPtr->outdata) != ICERR_OK) { 350 ICDecompress(infoPtr->hic, 0, infoPtr->inbih, infoPtr->indata, 351 infoPtr->outbih, infoPtr->outdata) != ICERR_OK) { 352 LeaveCriticalSection(&infoPtr->cs); 353 WARN("Decompression error\n"); 354 return FALSE; 355 } 356 357 if ((hDC = GetDC(infoPtr->hWnd)) != 0) { 358 ANIMATE_PaintFrame(infoPtr, hDC); 359 ReleaseDC(infoPtr->hWnd, hDC); 360 } 361 362 if (infoPtr->currFrame++ >= infoPtr->nToFrame) { 363 infoPtr->currFrame = infoPtr->nFromFrame; 364 if (infoPtr->nLoop != -1) { 365 if (--infoPtr->nLoop == 0) { 366 ANIMATE_DoStop(infoPtr); 367 } 368 } 369 } 352 370 LeaveCriticalSection(&infoPtr->cs); 353 WARN("Decompression error\n");354 return FALSE;355 }356 357 if ((hDC = GetDC(infoPtr->hWnd)) != 0) {358 ANIMATE_PaintFrame(infoPtr, hDC);359 ReleaseDC(infoPtr->hWnd, hDC);360 }361 362 if (infoPtr->currFrame++ >= infoPtr->nToFrame) {363 infoPtr->currFrame = infoPtr->nFromFrame;364 if (infoPtr->nLoop != -1) {365 if (--infoPtr->nLoop == 0) {366 ANIMATE_DoStop(infoPtr);367 }368 }369 }370 LeaveCriticalSection(&infoPtr->cs);371 371 372 372 return TRUE; … … 375 375 static DWORD CALLBACK ANIMATE_AnimationThread(LPVOID ptr_) 376 376 { 377 ANIMATE_INFO* 377 ANIMATE_INFO* infoPtr = (ANIMATE_INFO*)ptr_; 378 378 HDC hDC; 379 379 380 380 if(!infoPtr) 381 381 { … … 385 385 386 386 while(1) 387 { 388 if(GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_TRANSPARENT) 387 { 388 if(GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_TRANSPARENT) 389 389 { 390 390 hDC = GetDC(infoPtr->hWnd); 391 392 391 /* sometimes the animation window will be destroyed in between 392 * by the main program, so a ReleaseDC() error msg is possible */ 393 393 infoPtr->hbrushBG = SendMessageA(GetParent(infoPtr->hWnd),WM_CTLCOLORSTATIC,hDC, infoPtr->hWnd); 394 394 ReleaseDC(infoPtr->hWnd,hDC); 395 395 } 396 396 397 397 EnterCriticalSection(&infoPtr->cs); 398 398 ANIMATE_DrawFrame(infoPtr); 399 399 LeaveCriticalSection(&infoPtr->cs); 400 400 401 401 /* time is in microseconds, we should convert it to milliseconds */ 402 402 Sleep((infoPtr->mah.dwMicroSecPerFrame+500)/1000); … … 411 411 /* nothing opened */ 412 412 if (!infoPtr->hMMio) 413 413 return FALSE; 414 414 415 415 if (infoPtr->hThread || infoPtr->uTimer) { 416 417 416 FIXME("Already playing ? what should I do ??\n"); 417 ANIMATE_DoStop(infoPtr); 418 418 } 419 419 … … 423 423 424 424 if (infoPtr->nToFrame == 0xFFFF) 425 426 427 TRACE("(repeat=%d from=%d to=%d);\n", 428 425 infoPtr->nToFrame = infoPtr->mah.dwTotalFrames - 1; 426 427 TRACE("(repeat=%d from=%d to=%d);\n", 428 infoPtr->nLoop, infoPtr->nFromFrame, infoPtr->nToFrame); 429 429 430 430 if (infoPtr->nFromFrame >= infoPtr->nToFrame || 431 432 431 infoPtr->nToFrame >= infoPtr->mah.dwTotalFrames) 432 return FALSE; 433 433 434 434 infoPtr->currFrame = infoPtr->nFromFrame; 435 435 436 436 if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TIMER) { 437 438 439 437 TRACE("Using a timer\n"); 438 /* create a timer to display AVI */ 439 infoPtr->uTimer = SetTimer(hWnd, 1, infoPtr->mah.dwMicroSecPerFrame / 1000, NULL); 440 440 } else { 441 441 DWORD threadID; 442 442 443 443 TRACE("Using an animation thread\n"); 444 444 infoPtr->hThread = CreateThread(0,0,ANIMATE_AnimationThread,(LPVOID)infoPtr,0,0 &threadID); 445 445 if(!infoPtr->hThread) … … 448 448 return FALSE; 449 449 } 450 451 } 452 450 451 } 452 453 453 ANIMATE_Notify(infoPtr, ACN_START); 454 454 … … 459 459 static BOOL ANIMATE_GetAviInfo(ANIMATE_INFO *infoPtr) 460 460 { 461 MMCKINFO 462 MMCKINFO 463 MMCKINFO 464 MMCKINFO 465 DWORD 466 DWORD 461 MMCKINFO ckMainRIFF; 462 MMCKINFO mmckHead; 463 MMCKINFO mmckList; 464 MMCKINFO mmckInfo; 465 DWORD numFrame; 466 DWORD insize; 467 467 468 468 if (mmioDescend(infoPtr->hMMio, &ckMainRIFF, NULL, 0) != 0) { 469 470 469 WARN("Can't find 'RIFF' chunk\n"); 470 return FALSE; 471 471 } 472 472 473 473 if ((ckMainRIFF.ckid != FOURCC_RIFF) || 474 475 476 474 (ckMainRIFF.fccType != mmioFOURCC('A', 'V', 'I', ' '))) { 475 WARN("Can't find 'AVI ' chunk\n"); 476 return FALSE; 477 477 } 478 478 479 479 mmckHead.fccType = mmioFOURCC('h', 'd', 'r', 'l'); 480 480 if (mmioDescend(infoPtr->hMMio, &mmckHead, &ckMainRIFF, MMIO_FINDLIST) != 0) { 481 482 481 WARN("Can't find 'hdrl' list\n"); 482 return FALSE; 483 483 } 484 484 485 485 mmckInfo.ckid = mmioFOURCC('a', 'v', 'i', 'h'); 486 486 if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckHead, MMIO_FINDCHUNK) != 0) { 487 488 487 WARN("Can't find 'avih' chunk\n"); 488 return FALSE; 489 489 } 490 490 491 491 mmioRead(infoPtr->hMMio, (LPSTR)&infoPtr->mah, sizeof(infoPtr->mah)); 492 492 493 TRACE("mah.dwMicroSecPerFrame=%ld\n", 494 TRACE("mah.dwMaxBytesPerSec=%ld\n", 495 TRACE("mah.dwPaddingGranularity=%ld\n", 496 TRACE("mah.dwFlags=%ld\n", 497 TRACE("mah.dwTotalFrames=%ld\n", 498 TRACE("mah.dwInitialFrames=%ld\n", 499 TRACE("mah.dwStreams=%ld\n", 500 TRACE("mah.dwSuggestedBufferSize=%ld\n", 501 TRACE("mah.dwWidth=%ld\n", 502 TRACE("mah.dwHeight=%ld\n", 493 TRACE("mah.dwMicroSecPerFrame=%ld\n", infoPtr->mah.dwMicroSecPerFrame); 494 TRACE("mah.dwMaxBytesPerSec=%ld\n", infoPtr->mah.dwMaxBytesPerSec); 495 TRACE("mah.dwPaddingGranularity=%ld\n", infoPtr->mah.dwPaddingGranularity); 496 TRACE("mah.dwFlags=%ld\n", infoPtr->mah.dwFlags); 497 TRACE("mah.dwTotalFrames=%ld\n", infoPtr->mah.dwTotalFrames); 498 TRACE("mah.dwInitialFrames=%ld\n", infoPtr->mah.dwInitialFrames); 499 TRACE("mah.dwStreams=%ld\n", infoPtr->mah.dwStreams); 500 TRACE("mah.dwSuggestedBufferSize=%ld\n", infoPtr->mah.dwSuggestedBufferSize); 501 TRACE("mah.dwWidth=%ld\n", infoPtr->mah.dwWidth); 502 TRACE("mah.dwHeight=%ld\n", infoPtr->mah.dwHeight); 503 503 504 504 mmioAscend(infoPtr->hMMio, &mmckInfo, 0); … … 506 506 mmckList.fccType = mmioFOURCC('s', 't', 'r', 'l'); 507 507 if (mmioDescend(infoPtr->hMMio, &mmckList, &mmckHead, MMIO_FINDLIST) != 0) { 508 509 508 WARN("Can't find 'strl' list\n"); 509 return FALSE; 510 510 } 511 511 512 512 mmckInfo.ckid = mmioFOURCC('s', 't', 'r', 'h'); 513 513 if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, MMIO_FINDCHUNK) != 0) { 514 515 514 WARN("Can't find 'strh' chunk\n"); 515 return FALSE; 516 516 } 517 517 518 518 mmioRead(infoPtr->hMMio, (LPSTR)&infoPtr->ash, sizeof(infoPtr->ash)); 519 519 520 TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(infoPtr->ash.fccType)),521 HIBYTE(LOWORD(infoPtr->ash.fccType)), 522 LOBYTE(HIWORD(infoPtr->ash.fccType)), 523 524 TRACE("ash.fccHandler='%c%c%c%c'\n", LOBYTE(LOWORD(infoPtr->ash.fccHandler)),525 HIBYTE(LOWORD(infoPtr->ash.fccHandler)), 526 LOBYTE(HIWORD(infoPtr->ash.fccHandler)), 527 528 TRACE("ash.dwFlags=%ld\n", 529 TRACE("ash.wPriority=%d\n", 530 TRACE("ash.wLanguage=%d\n", 531 TRACE("ash.dwInitialFrames=%ld\n", 532 TRACE("ash.dwScale=%ld\n", 533 TRACE("ash.dwRate=%ld\n", 534 TRACE("ash.dwStart=%ld\n", 535 TRACE("ash.dwLength=%ld\n", 536 TRACE("ash.dwSuggestedBufferSize=%ld\n", 537 TRACE("ash.dwQuality=%ld\n", 538 TRACE("ash.dwSampleSize=%ld\n", 539 TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", infoPtr->ash.rcFrame.top, infoPtr->ash.rcFrame.left,540 520 TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(infoPtr->ash.fccType)), 521 HIBYTE(LOWORD(infoPtr->ash.fccType)), 522 LOBYTE(HIWORD(infoPtr->ash.fccType)), 523 HIBYTE(HIWORD(infoPtr->ash.fccType))); 524 TRACE("ash.fccHandler='%c%c%c%c'\n", LOBYTE(LOWORD(infoPtr->ash.fccHandler)), 525 HIBYTE(LOWORD(infoPtr->ash.fccHandler)), 526 LOBYTE(HIWORD(infoPtr->ash.fccHandler)), 527 HIBYTE(HIWORD(infoPtr->ash.fccHandler))); 528 TRACE("ash.dwFlags=%ld\n", infoPtr->ash.dwFlags); 529 TRACE("ash.wPriority=%d\n", infoPtr->ash.wPriority); 530 TRACE("ash.wLanguage=%d\n", infoPtr->ash.wLanguage); 531 TRACE("ash.dwInitialFrames=%ld\n", infoPtr->ash.dwInitialFrames); 532 TRACE("ash.dwScale=%ld\n", infoPtr->ash.dwScale); 533 TRACE("ash.dwRate=%ld\n", infoPtr->ash.dwRate); 534 TRACE("ash.dwStart=%ld\n", infoPtr->ash.dwStart); 535 TRACE("ash.dwLength=%ld\n", infoPtr->ash.dwLength); 536 TRACE("ash.dwSuggestedBufferSize=%ld\n", infoPtr->ash.dwSuggestedBufferSize); 537 TRACE("ash.dwQuality=%ld\n", infoPtr->ash.dwQuality); 538 TRACE("ash.dwSampleSize=%ld\n", infoPtr->ash.dwSampleSize); 539 TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", infoPtr->ash.rcFrame.top, infoPtr->ash.rcFrame.left, 540 infoPtr->ash.rcFrame.bottom, infoPtr->ash.rcFrame.right); 541 541 542 542 mmioAscend(infoPtr->hMMio, &mmckInfo, 0); … … 544 544 mmckInfo.ckid = mmioFOURCC('s', 't', 'r', 'f'); 545 545 if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, MMIO_FINDCHUNK) != 0) { 546 547 546 WARN("Can't find 'strh' chunk\n"); 547 return FALSE; 548 548 } 549 549 550 550 infoPtr->inbih = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize); 551 551 if (!infoPtr->inbih) { 552 553 552 WARN("Can't alloc input BIH\n"); 553 return FALSE; 554 554 } 555 555 556 556 mmioRead(infoPtr->hMMio, (LPSTR)infoPtr->inbih, mmckInfo.cksize); 557 557 558 TRACE("bih.biSize=%ld\n", 559 TRACE("bih.biWidth=%ld\n", 560 TRACE("bih.biHeight=%ld\n", 561 TRACE("bih.biPlanes=%d\n", 562 TRACE("bih.biBitCount=%d\n", 563 TRACE("bih.biCompression=%ld\n", 564 TRACE("bih.biSizeImage=%ld\n", 565 TRACE("bih.biXPelsPerMeter=%ld\n", 566 TRACE("bih.biYPelsPerMeter=%ld\n", 567 TRACE("bih.biClrUsed=%ld\n", 568 TRACE("bih.biClrImportant=%ld\n", 558 TRACE("bih.biSize=%ld\n", infoPtr->inbih->biSize); 559 TRACE("bih.biWidth=%ld\n", infoPtr->inbih->biWidth); 560 TRACE("bih.biHeight=%ld\n", infoPtr->inbih->biHeight); 561 TRACE("bih.biPlanes=%d\n", infoPtr->inbih->biPlanes); 562 TRACE("bih.biBitCount=%d\n", infoPtr->inbih->biBitCount); 563 TRACE("bih.biCompression=%ld\n", infoPtr->inbih->biCompression); 564 TRACE("bih.biSizeImage=%ld\n", infoPtr->inbih->biSizeImage); 565 TRACE("bih.biXPelsPerMeter=%ld\n", infoPtr->inbih->biXPelsPerMeter); 566 TRACE("bih.biYPelsPerMeter=%ld\n", infoPtr->inbih->biYPelsPerMeter); 567 TRACE("bih.biClrUsed=%ld\n", infoPtr->inbih->biClrUsed); 568 TRACE("bih.biClrImportant=%ld\n", infoPtr->inbih->biClrImportant); 569 569 570 570 mmioAscend(infoPtr->hMMio, &mmckInfo, 0); 571 571 572 572 mmioAscend(infoPtr->hMMio, &mmckList, 0); 573 573 574 574 #if 0 575 575 /* an AVI has 0 or 1 video stream, and to be animated should not contain 576 * an audio stream, so only one strl is allowed 576 * an audio stream, so only one strl is allowed 577 577 */ 578 578 mmckList.fccType = mmioFOURCC('s', 't', 'r', 'l'); 579 579 if (mmioDescend(infoPtr->hMMio, &mmckList, &mmckHead, MMIO_FINDLIST) == 0) { 580 581 580 WARN("There should be a single 'strl' list\n"); 581 return FALSE; 582 582 } 583 583 #endif … … 589 589 mmckList.fccType = mmioFOURCC('m', 'o', 'v', 'i'); 590 590 if (mmioDescend(infoPtr->hMMio, &mmckList, &ckMainRIFF, MMIO_FINDLIST) != 0) { 591 592 591 WARN("Can't find 'movi' list\n"); 592 return FALSE; 593 593 } 594 594 595 595 /* FIXME: should handle the 'rec ' LIST when present */ 596 596 597 infoPtr->lpIndex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 598 597 infoPtr->lpIndex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 598 infoPtr->mah.dwTotalFrames * sizeof(DWORD)); 599 599 if (!infoPtr->lpIndex) { 600 601 600 WARN("Can't alloc index array\n"); 601 return FALSE; 602 602 } 603 603 604 604 numFrame = insize = 0; 605 while (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, 0) == 0 && 606 607 608 609 610 611 605 while (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, 0) == 0 && 606 numFrame < infoPtr->mah.dwTotalFrames) { 607 infoPtr->lpIndex[numFrame] = mmckInfo.dwDataOffset; 608 if (insize < mmckInfo.cksize) 609 insize = mmckInfo.cksize; 610 numFrame++; 611 mmioAscend(infoPtr->hMMio, &mmckInfo, 0); 612 612 } 613 613 if (numFrame != infoPtr->mah.dwTotalFrames) { 614 615 614 WARN("Found %ld frames (/%ld)\n", numFrame, infoPtr->mah.dwTotalFrames); 615 return FALSE; 616 616 } 617 617 if (insize > infoPtr->ash.dwSuggestedBufferSize) { 618 619 618 WARN("insize=%ld suggestedSize=%ld\n", insize, infoPtr->ash.dwSuggestedBufferSize); 619 infoPtr->ash.dwSuggestedBufferSize = insize; 620 620 } 621 621 622 622 infoPtr->indata = HeapAlloc(GetProcessHeap(), 0, infoPtr->ash.dwSuggestedBufferSize); 623 623 if (!infoPtr->indata) { 624 625 624 WARN("Can't alloc input buffer\n"); 625 return FALSE; 626 626 } 627 627 … … 632 632 static BOOL ANIMATE_GetAviCodec(ANIMATE_INFO *infoPtr) 633 633 { 634 DWORD 634 DWORD outSize; 635 635 636 636 /* check uncompressed AVI */ … … 638 638 (infoPtr->ash.fccHandler == mmioFOURCC('R', 'L', 'E', ' '))) 639 639 { 640 infoPtr->hic = 0; 641 640 infoPtr->hic = 0; 641 return TRUE; 642 642 } 643 643 … … 645 645 infoPtr->hic = ICOpen(ICTYPE_VIDEO, infoPtr->ash.fccHandler, ICMODE_DECOMPRESS); 646 646 if (!infoPtr->hic) { 647 648 649 } 650 651 outSize = ICSendMessage(infoPtr->hic, ICM_DECOMPRESS_GET_FORMAT, 652 647 WARN("Can't load codec for the file\n"); 648 return FALSE; 649 } 650 651 outSize = ICSendMessage(infoPtr->hic, ICM_DECOMPRESS_GET_FORMAT, 652 (DWORD)infoPtr->inbih, 0L); 653 653 654 654 infoPtr->outbih = HeapAlloc(GetProcessHeap(), 0, outSize); 655 655 if (!infoPtr->outbih) { 656 657 658 } 659 660 if (ICSendMessage(infoPtr->hic, ICM_DECOMPRESS_GET_FORMAT, 661 662 663 656 WARN("Can't alloc output BIH\n"); 657 return FALSE; 658 } 659 660 if (ICSendMessage(infoPtr->hic, ICM_DECOMPRESS_GET_FORMAT, 661 (DWORD)infoPtr->inbih, (DWORD)infoPtr->outbih) != ICERR_OK) { 662 WARN("Can't get output BIH\n"); 663 return FALSE; 664 664 } 665 665 666 666 infoPtr->outdata = HeapAlloc(GetProcessHeap(), 0, infoPtr->outbih->biSizeImage); 667 667 if (!infoPtr->outdata) { 668 669 670 } 671 672 if (ICSendMessage(infoPtr->hic, ICM_DECOMPRESS_BEGIN, 673 674 675 668 WARN("Can't alloc output buffer\n"); 669 return FALSE; 670 } 671 672 if (ICSendMessage(infoPtr->hic, ICM_DECOMPRESS_BEGIN, 673 (DWORD)infoPtr->inbih, (DWORD)infoPtr->outbih) != ICERR_OK) { 674 WARN("Can't begin decompression\n"); 675 return FALSE; 676 676 } 677 677 … … 691 691 692 692 if (!lParam) { 693 694 695 } 696 693 TRACE("Closing avi!\n"); 694 return TRUE; 695 } 696 697 697 if (!hInstance) 698 698 hInstance = GetWindowLongA(hWnd, GWL_HINSTANCE); … … 719 719 #else 720 720 if (HIWORD(lParam)) { 721 722 723 724 725 726 727 728 729 721 TRACE("(\"%s\");\n", (LPSTR)lParam); 722 723 if (!ANIMATE_LoadResA(infoPtr, hInstance, (LPSTR)lParam)) { 724 TRACE("No AVI resource found!\n"); 725 if (!ANIMATE_LoadFileA(infoPtr, (LPSTR)lParam)) { 726 WARN("No AVI file found!\n"); 727 return FALSE; 728 } 729 } 730 730 } else { 731 732 733 734 735 736 737 731 TRACE("(%u);\n", (WORD)LOWORD(lParam)); 732 733 if (!ANIMATE_LoadResA(infoPtr, hInstance, 734 MAKEINTRESOURCEA((INT)lParam))) { 735 WARN("No AVI resource found!\n"); 736 return FALSE; 737 } 738 738 } 739 739 #endif 740 740 if (!ANIMATE_GetAviInfo(infoPtr)) { 741 742 743 741 WARN("Can't get AVI information\n"); 742 ANIMATE_Free(infoPtr); 743 return FALSE; 744 744 } 745 745 746 746 if (!ANIMATE_GetAviCodec(infoPtr)) { 747 748 749 747 WARN("Can't get AVI Codec\n"); 748 ANIMATE_Free(infoPtr); 749 return FALSE; 750 750 } 751 751 752 752 if (!GetWindowLongA(hWnd, GWL_STYLE) & ACS_CENTER) { 753 754 753 SetWindowPos(hWnd, 0, 0, 0, infoPtr->mah.dwWidth, infoPtr->mah.dwHeight, 754 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER); 755 755 } 756 756 757 757 if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_AUTOPLAY) { 758 758 return ANIMATE_Play(hWnd, -1, (LPARAM)MAKELONG(0, infoPtr->mah.dwTotalFrames-1)); 759 759 } 760 760 … … 771 771 /* nothing opened */ 772 772 if (!infoPtr->hMMio) 773 773 return FALSE; 774 774 775 775 ANIMATE_DoStop(infoPtr); … … 780 780 static LRESULT ANIMATE_Create(HWND hWnd, WPARAM wParam, LPARAM lParam) 781 781 { 782 ANIMATE_INFO* 782 ANIMATE_INFO* infoPtr; 783 783 784 784 /* allocate memory for info structure */ … … 789 789 #endif 790 790 if (!infoPtr) { 791 792 791 ERR("could not allocate info memory!\n"); 792 return 0; 793 793 } 794 794 … … 802 802 803 803 InitializeCriticalSection(&infoPtr->cs); 804 804 805 805 return 0; 806 806 } … … 826 826 { 827 827 RECT rect; 828 HBRUSH hBrush = 0; 829 830 if(GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT) 828 HBRUSH hBrush = 0; 829 830 if(GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT) 831 831 { 832 hBrush = SendMessageA(GetParent(hWnd),WM_CTLCOLORSTATIC,(HDC)wParam, hWnd); 832 hBrush = SendMessageA(GetParent(hWnd),WM_CTLCOLORSTATIC,(HDC)wParam, hWnd); 833 833 } 834 834 … … 842 842 { 843 843 if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_CENTER) { 844 844 InvalidateRect(hWnd, NULL, TRUE); 845 845 } 846 846 return TRUE; … … 851 851 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hWnd, uMsg, wParam, lParam); 852 852 if (!ANIMATE_GetInfoPtr(hWnd) && (uMsg != WM_NCCREATE)) 853 853 return DefWindowProcA(hWnd, uMsg, wParam, lParam); 854 854 switch (uMsg) 855 855 { … … 862 862 #else 863 863 case ACM_OPENA: 864 865 866 /*case ACM_OPEN32W: FIXME!! */867 /*return ANIMATE_Open32W(hWnd, wParam, lParam); */868 #endif 869 864 return ANIMATE_OpenA(hWnd, wParam, lParam); 865 866 /* case ACM_OPEN32W: FIXME!! */ 867 /* return ANIMATE_Open32W(hWnd, wParam, lParam); */ 868 #endif 869 870 870 case ACM_PLAY: 871 872 871 return ANIMATE_Play(hWnd, wParam, lParam); 872 873 873 case ACM_STOP: 874 875 874 return ANIMATE_Stop(hWnd, wParam, lParam); 875 876 876 case WM_NCCREATE: 877 878 879 877 ANIMATE_Create(hWnd, wParam, lParam); 878 return DefWindowProcA(hWnd, uMsg, wParam, lParam); 879 880 880 case WM_NCHITTEST: 881 881 return HTTRANSPARENT; 882 882 883 883 case WM_DESTROY: 884 885 886 884 ANIMATE_Destroy(hWnd, wParam, lParam); 885 return DefWindowProcA(hWnd, uMsg, wParam, lParam); 886 887 887 case WM_ERASEBKGND: 888 889 890 891 /* 888 ANIMATE_EraseBackground(hWnd, wParam, lParam); 889 break; 890 891 /* case WM_STYLECHANGED: FIXME shall we do something ?? */ 892 892 893 893 case WM_TIMER: 894 894 if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT) 895 895 { 896 896 ANIMATE_INFO* infoPtr = ANIMATE_GetInfoPtr(hWnd); 897 897 infoPtr->hbrushBG = SendMessageA(GetParent(hWnd),WM_CTLCOLORSTATIC,(HDC)wParam, hWnd); 898 898 } 899 900 899 return ANIMATE_DrawFrame(ANIMATE_GetInfoPtr(hWnd)); 900 901 901 case WM_CLOSE: 902 903 902 ANIMATE_Free(ANIMATE_GetInfoPtr(hWnd)); 903 return TRUE; 904 904 905 905 case WM_PAINT: 906 906 { 907 907 ANIMATE_INFO* infoPtr = ANIMATE_GetInfoPtr(hWnd); 908 908 909 909 /* the animation isn't playing, don't paint */ 910 911 912 913 910 if(!infoPtr->uTimer && !infoPtr->hThread) 911 /* default paint handling */ 912 return DefWindowProcA(hWnd, uMsg, wParam, lParam); 913 914 914 if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT) 915 915 infoPtr->hbrushBG = SendMessageA(GetParent(hWnd), WM_CTLCOLORSTATIC, 916 917 916 (HDC)wParam, hWnd); 917 918 918 if (wParam) 919 919 { … … 924 924 else 925 925 { 926 927 926 PAINTSTRUCT ps; 927 HDC hDC = BeginPaint(hWnd, &ps); 928 928 929 929 EnterCriticalSection(&infoPtr->cs); 930 930 ANIMATE_PaintFrame(infoPtr, hDC); 931 931 LeaveCriticalSection(&infoPtr->cs); 932 933 EndPaint(hWnd, &ps); 932 933 EndPaint(hWnd, &ps); 934 } 934 935 } 935 } 936 break; 936 break; 937 937 938 938 case WM_SIZE: 939 940 939 ANIMATE_Size(hWnd, wParam, lParam); 940 return DefWindowProcA(hWnd, uMsg, wParam, lParam); 941 941 942 942 default: 943 944 945 943 if (uMsg >= WM_USER) 944 ERR("unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam); 945 946 946 #ifdef __WIN32OS2__ 947 947 return defComCtl32ProcA (hWnd, uMsg, wParam, lParam); 948 948 #else 949 949 return DefWindowProcA(hWnd, uMsg, wParam, lParam); 950 950 #endif 951 951 } … … 966 966 wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); 967 967 wndClass.lpszClassName = ANIMATE_CLASSA; 968 968 969 969 RegisterClassA(&wndClass); 970 970 } -
trunk/src/comctl32/comboex.c
r6705 r6709 4 4 * result in a FIXME: 5 5 * CBES_EX_NOEDITIMAGEINDENT 6 * 7 * 8 * 6 * CBES_EX_PATHWORDBREAKPROC 7 * CBES_EX_NOSIZELIMIT 8 * CBES_EX_CASESENSITIVE 9 9 * 2. None of the following callback items are implemented. Therefor 10 10 * no CBEN_GETDISPINFO notifies are issued. Use in either CBEM_INSERTITEM … … 37 37 * generate message sequence similar to native DLL. 38 38 * 2. Handle case where CBEM_SETITEM is called to display data in EDIT 39 * Control. 39 * Control. 40 40 * 3. Add override for WNDPROC for the EDIT control (reqed for VK_RETURN). 41 41 * 4. Dump input data for things using COMBOBOXEXITEM{A|W}. … … 55 55 * 3. Lock image selected status to focus state of edit control if 56 56 * edit control exists. Mimics native actions. 57 * 4. Implemented WM_SETFOCUS in EditWndProc to track status of 57 * 4. Implemented WM_SETFOCUS in EditWndProc to track status of 58 58 * focus for 3 above. 59 59 * 5. The LBN_SELCHANGE is just for documentation purposes. … … 70 70 * 71 71 * mod 6 72 * 1. Add support for WM_NOTIFYFORMAT (both incoming and outgoing) and do 72 * 1. Add support for WM_NOTIFYFORMAT (both incoming and outgoing) and do 73 73 * WM_NOTIFY correctly based on results. 74 74 * 2. Fix memory leaks of text strings in COMBOEX_WM_DELETEITEM. 75 75 * 3. Add routines to handle special cases of NMCBEENDEDIT and NMCOMBOXEX 76 * so translation to ANSI is done correctly. 76 * so translation to ANSI is done correctly. 77 77 * 4. Fix some issues with COMBOEX_DrawItem. 78 78 * … … 150 150 /* 151 151 * Special flag set in DRAWITEMSTRUCT itemState field. It is set by 152 * the ComboEx version of the Combo Window Proc so that when the 153 * WM_DRAWITEM message is then passed to ComboEx, we know that this 152 * the ComboEx version of the Combo Window Proc so that when the 153 * WM_DRAWITEM message is then passed to ComboEx, we know that this 154 154 * particular WM_DRAWITEM message is for listbox only items. Any messasges 155 155 * without this flag is then for the Edit control field. 156 156 * 157 * We really cannot use the ODS_COMBOBOXEDIT flag because MSDN states that 157 * We really cannot use the ODS_COMBOBOXEDIT flag because MSDN states that 158 158 * only version 4.0 applications will have ODS_COMBOBOXEDIT set. 159 159 */ … … 189 189 if (TRACE_ON(comboex)){ 190 190 TRACE("item %p - mask=%08x, pszText=%p, cchTM=%d, iImage=%d\n", 191 192 191 item, item->mask, item->pszText, item->cchTextMax, 192 item->iImage); 193 193 TRACE("item %p - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n", 194 194 item, item->iSelectedImage, item->iOverlay, item->iIndent, item->lParam); 195 195 if ((item->mask & CBEIF_TEXT) && item->pszText) 196 197 196 TRACE("item %p - pszText=%s\n", 197 item, debugstr_w((const WCHAR *)item->pszText)); 198 198 } 199 199 } … … 205 205 if (TRACE_ON(comboex)){ 206 206 TRACE("input - mask=%08x, iItem=%d, pszText=%p, cchTM=%d, iImage=%d\n", 207 208 207 input->mask, input->iItem, input->pszText, input->cchTextMax, 208 input->iImage); 209 209 if ((input->mask & CBEIF_TEXT) && input->pszText) { 210 211 TRACE("input - pszText=<%s>\n", 212 213 else 214 TRACE("input - pszText=<%s>\n", 215 210 if (true_for_w) 211 TRACE("input - pszText=<%s>\n", 212 debugstr_w((const WCHAR *)input->pszText)); 213 else 214 TRACE("input - pszText=<%s>\n", 215 debugstr_a((const char *)input->pszText)); 216 216 } 217 217 TRACE("input - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n", 218 218 input->iSelectedImage, input->iOverlay, input->iIndent, input->lParam); 219 219 } 220 220 } … … 226 226 COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); 227 227 228 if (infoPtr->hwndCombo) 229 228 if (infoPtr->hwndCombo) 229 return SendMessageA (infoPtr->hwndCombo, uMsg, wParam, lParam); 230 230 231 231 return 0; … … 241 241 hdr->code = code; 242 242 if (infoPtr->NtfUnicode) 243 244 243 return SendMessageW (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0, 244 (LPARAM)hdr); 245 245 else 246 247 246 return SendMessageA (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0, 247 (LPARAM)hdr); 248 248 } 249 249 … … 259 259 hdr->hdr.code = code; 260 260 if (infoPtr->NtfUnicode) 261 262 261 return SendMessageW (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0, 262 (LPARAM)hdr); 263 263 else { 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 264 LPWSTR str, ostr = NULL; 265 INT ret, len = 0; 266 267 if (hdr->ceItem.mask & CBEIF_TEXT) { 268 ostr = hdr->ceItem.pszText; 269 str = ostr; 270 if (!str) str = (LPWSTR)L""; 271 len = WideCharToMultiByte (CP_ACP, 0, str, -1, 0, 0, NULL, NULL); 272 if (len > 0) { 273 hdr->ceItem.pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(CHAR)); 274 WideCharToMultiByte (CP_ACP, 0, str, -1, (LPSTR)hdr->ceItem.pszText, 275 len, NULL, NULL); 276 } 277 } 278 279 ret = SendMessageA (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0, 280 (LPARAM)hdr); 281 if (hdr->ceItem.mask & CBEIF_TEXT) { 282 if (len > 0) 283 COMCTL32_Free (hdr->ceItem.pszText); 284 hdr->ceItem.pszText = ostr; 285 } 286 return ret; 287 287 } 288 288 } … … 299 299 hdr->hdr.code = (infoPtr->NtfUnicode) ? CBEN_ENDEDITW : CBEN_ENDEDITA; 300 300 if (infoPtr->NtfUnicode) 301 302 301 return SendMessageW (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0, 302 (LPARAM)hdr); 303 303 else { 304 305 306 307 308 309 310 311 312 313 304 NMCBEENDEDITA ansi; 305 306 memcpy (&ansi.hdr, &hdr->hdr, sizeof(NMHDR)); 307 ansi.fChanged = hdr->fChanged; 308 ansi.iNewSelection = hdr->iNewSelection; 309 WideCharToMultiByte (CP_ACP, 0, itemText, -1, 310 (LPSTR)&ansi.szText, CBEMAXSTRLEN, NULL, NULL); 311 ansi.iWhy = hdr->iWhy; 312 return SendMessageA (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0, 313 (LPARAM)&ansi); 314 314 } 315 315 } … … 340 340 } 341 341 if (cit->mask & CBEIF_IMAGE) 342 342 cit->iImage = item->iImage; 343 343 if (cit->mask & CBEIF_SELECTEDIMAGE) 344 344 cit->iSelectedImage = item->iSelectedImage; 345 345 if (cit->mask & CBEIF_OVERLAY) 346 346 cit->iOverlay = item->iOverlay; 347 347 if (cit->mask & CBEIF_INDENT) 348 348 cit->iIndent = item->iIndent; 349 349 if (cit->mask & CBEIF_LPARAM) 350 350 cit->lParam = item->lParam; 351 351 352 352 } … … 364 364 iinfo.rcImage.left = iinfo.rcImage.right = 0; 365 365 if (infoPtr->himl) { 366 367 366 ImageList_GetImageInfo(infoPtr->himl, 0, &iinfo); 367 xoff = iinfo.rcImage.right - iinfo.rcImage.left + CBE_SEP; 368 368 } 369 369 GetClientRect (infoPtr->hwndCombo, &rect); … … 380 380 381 381 TRACE("Combo client (%d,%d)-(%d,%d), setting Edit to (%d,%d)-(%d,%d)\n", 382 383 382 rect.left, rect.top, rect.right, rect.bottom, 383 x, y, x + w, y + h); 384 384 SetWindowPos(infoPtr->hwndEdit, HWND_TOP, 385 386 387 385 x, y, 386 w, h, 387 SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER); 388 388 } 389 389 … … 399 399 cy = mysize.cy + CBE_EXTRA; 400 400 if (infoPtr->himl) { 401 402 403 401 ImageList_GetImageInfo(infoPtr->himl, 0, &iinfo); 402 cy = max (iinfo.rcImage.bottom - iinfo.rcImage.top, cy); 403 TRACE("upgraded height due to image: height=%d\n", cy); 404 404 } 405 405 SendMessageW (hwnd, CB_SETITEMHEIGHT, (WPARAM) -1, (LPARAM) cy); 406 406 if (infoPtr->hwndCombo) 407 407 SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT, 408 408 (WPARAM) 0, (LPARAM) cy); 409 409 } 410 410 … … 419 419 /* EM_SETSEL32 (0,-1) */ 420 420 if (item->mask & CBEIF_TEXT) { 421 422 423 424 } 425 } 426 427 421 SendMessageW (infoPtr->hwndEdit, WM_SETTEXT, 0, (LPARAM)item->pszText); 422 SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0); 423 SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1); 424 } 425 } 426 427 428 428 static CBE_ITEMDATA * 429 429 COMBOEX_FindItem(COMBOEX_INFO *infoPtr, INT index) … … 433 433 434 434 if ((index > infoPtr->nb_items) || (index < -1)) 435 435 return 0; 436 436 if (index == -1) 437 437 return infoPtr->edit; 438 438 item = infoPtr->items; 439 439 i = infoPtr->nb_items - 1; … … 441 441 /* find the item in the list */ 442 442 while (item && (i > index)) { 443 444 443 item = (CBE_ITEMDATA *)item->next; 444 i--; 445 445 } 446 446 if (!item || (i != index)) { 447 448 447 FIXME("COMBOBOXEX item structures broken. Please report!\n"); 448 return 0; 449 449 } 450 450 return item; … … 456 456 { 457 457 if (item->pszText == LPSTR_TEXTCALLBACKW) 458 458 FIXME("Callback not implemented yet for pszText\n"); 459 459 if (item->iImage == I_IMAGECALLBACK) 460 460 FIXME("Callback not implemented yet for iImage\n"); 461 461 if (item->iSelectedImage == I_IMAGECALLBACK) 462 462 FIXME("Callback not implemented yet for iSelectedImage\n"); 463 463 if (item->iOverlay == I_IMAGECALLBACK) 464 464 FIXME("Callback not implemented yet for iOverlay\n"); 465 465 if (item->iIndent == I_INDENTCALLBACK) 466 466 FIXME("Callback not implemented yet for iIndent\n"); 467 467 } 468 468 … … 482 482 /* if item number requested does not exist then return failure */ 483 483 if ((index > infoPtr->nb_items) || (index < 0)) { 484 485 484 ERR("attempt to delete item that does not exist\n"); 485 return CB_ERR; 486 486 } 487 487 488 488 if (!(item = COMBOEX_FindItem(infoPtr, index))) { 489 490 489 ERR("attempt to delete item that was not found!\n"); 490 return CB_ERR; 491 491 } 492 492 … … 515 515 516 516 if ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN) 517 517 return 0; 518 518 519 519 TRACE("-- 0x%x\n", infoPtr->hwndEdit); … … 560 560 /* if item number requested does not exist then return failure */ 561 561 if ((index > infoPtr->nb_items) || (index < -1)) { 562 563 562 ERR("attempt to get item that does not exist\n"); 563 return 0; 564 564 } 565 565 566 566 /* if the item is the edit control and there is no edit control, skip */ 567 if ((index == -1) && 567 if ((index == -1) && 568 568 ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN)) 569 569 return 0; 570 570 571 571 if (!(item = COMBOEX_FindItem(infoPtr, index))) { 572 573 572 ERR("attempt to get item that was not found!\n"); 573 return 0; 574 574 } 575 575 … … 594 594 595 595 len = WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1, 0, 0, NULL, NULL); 596 if (len > 0) 597 WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1, 598 596 if (len > 0) 597 WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1, 598 cit->pszText, cit->cchTextMax, NULL, NULL); 599 599 600 600 cit->iImage = tmpcit.iImage; … … 613 613 COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); 614 614 615 TRACE("%s hwnd=0x%x\n", 616 615 TRACE("%s hwnd=0x%x\n", 616 infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd); 617 617 618 618 return infoPtr->bUnicode; … … 626 626 627 627 if ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN) 628 629 if ((infoPtr->flags & (WCBE_ACTEDIT | WCBE_EDITCHG)) == 630 631 628 return FALSE; 629 if ((infoPtr->flags & (WCBE_ACTEDIT | WCBE_EDITCHG)) == 630 (WCBE_ACTEDIT | WCBE_EDITCHG)) 631 return TRUE; 632 632 return FALSE; 633 633 } … … 661 661 /* fast path for iItem = -1 */ 662 662 item->next = infoPtr->items; 663 663 infoPtr->items = item; 664 664 } 665 665 else { 666 666 INT i = infoPtr->nb_items-1; 667 668 669 670 671 672 673 674 675 676 677 678 679 667 CBE_ITEMDATA *moving = infoPtr->items; 668 669 while ((i > index) && moving) { 670 moving = (CBE_ITEMDATA *)moving->next; 671 i--; 672 } 673 if (!moving) { 674 FIXME("COMBOBOXEX item structures broken. Please report!\n"); 675 COMCTL32_Free(item); 676 return -1; 677 } 678 item->next = moving->next; 679 moving->next = item; 680 680 } 681 681 … … 684 684 if (item->mask & CBEIF_TEXT) { 685 685 LPWSTR str; 686 686 INT len; 687 687 688 688 str = cit->pszText; 689 689 if (!str) str = (LPWSTR) L""; 690 691 692 693 694 695 696 690 len = strlenW (str); 691 if (len > 0) { 692 item->pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR)); 693 strcpyW (item->pszText, str); 694 } 695 else 696 item->pszText = NULL; 697 697 item->cchTextMax = cit->cchTextMax; 698 698 } … … 713 713 COMBOEX_DumpItem (item); 714 714 715 SendMessageW (infoPtr->hwndCombo, CB_INSERTSTRING, 716 715 SendMessageW (infoPtr->hwndCombo, CB_INSERTSTRING, 716 (WPARAM)cit->iItem, (LPARAM)item); 717 717 718 718 COMBOEX_CopyItem (infoPtr, item, &nmcit.ceItem); … … 727 727 COMBOEX_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) 728 728 { 729 COMBOBOXEXITEMA 730 COMBOBOXEXITEMW 731 LRESULT 729 COMBOBOXEXITEMA *cit = (COMBOBOXEXITEMA *) lParam; 730 COMBOBOXEXITEMW citW; 731 LRESULT ret; 732 732 733 733 memcpy(&citW,cit,sizeof(COMBOBOXEXITEMA)); 734 734 if (cit->mask & CBEIF_TEXT) { 735 735 LPSTR str; 736 736 INT len; 737 737 738 738 str = cit->pszText; 739 739 if (!str) str=""; 740 741 742 743 744 740 len = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0); 741 if (len > 0) { 742 citW.pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR)); 743 MultiByteToWideChar (CP_ACP, 0, str, -1, citW.pszText, len); 744 } 745 745 } 746 746 ret = COMBOEX_InsertItemW(hwnd,wParam,(LPARAM)&citW);; 747 747 748 748 if (cit->mask & CBEIF_TEXT) 749 749 COMCTL32_Free(citW.pszText); 750 750 return ret; 751 751 } … … 763 763 764 764 if (lParam & (CBES_EX_NOEDITIMAGEINDENT | 765 766 767 768 765 CBES_EX_PATHWORDBREAKPROC | 766 CBES_EX_NOSIZELIMIT | 767 CBES_EX_CASESENSITIVE)) 768 FIXME("Extended style not implemented %08lx\n", lParam); 769 769 770 770 if ((DWORD)wParam) { 771 771 infoPtr->dwExtStyle = (infoPtr->dwExtStyle & ~(DWORD)wParam) | (DWORD)lParam; 772 772 } 773 773 else 774 774 infoPtr->dwExtStyle = (DWORD)lParam; 775 775 776 776 /* … … 778 778 */ 779 779 if ((infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE) ^ 780 781 782 783 784 785 786 787 780 (dwTemp & CBES_EX_NOEDITIMAGE)) { 781 /* if state of EX_NOEDITIMAGE changes, invalidate all */ 782 TRACE("EX_NOEDITIMAGE state changed to %ld\n", 783 infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE); 784 InvalidateRect (hwnd, NULL, TRUE); 785 COMBOEX_AdjustEditPos (infoPtr); 786 if (infoPtr->hwndEdit) 787 InvalidateRect (infoPtr->hwndEdit, NULL, TRUE); 788 788 } 789 789 … … 826 826 /* if item number requested does not exist then return failure */ 827 827 if ((index > infoPtr->nb_items) || (index < -1)) { 828 829 828 ERR("attempt to set item that does not exist yet!\n"); 829 return 0; 830 830 } 831 831 832 832 /* if the item is the edit control and there is no edit control, skip */ 833 if ((index == -1) && 833 if ((index == -1) && 834 834 ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN)) 835 835 return 0; 836 836 837 837 if (!(item = COMBOEX_FindItem(infoPtr, index))) { 838 839 840 } 841 842 /* add/change stuff to the internal item structure */ 838 ERR("attempt to set item that was not found!\n"); 839 return 0; 840 } 841 842 /* add/change stuff to the internal item structure */ 843 843 item->mask |= cit->mask; 844 844 if (cit->mask & CBEIF_TEXT) { 845 845 LPWSTR str; 846 847 846 INT len; 847 WCHAR emptystr[1] = {0}; 848 848 849 849 str = cit->pszText; 850 850 if (!str) str=emptystr; 851 852 853 854 855 851 len = strlenW(str); 852 if (len > 0) { 853 item->pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR)); 854 strcpyW(item->pszText,str); 855 } 856 856 item->cchTextMax = cit->cchTextMax; 857 857 } … … 873 873 /* if original request was to update edit control, do some fast foot work */ 874 874 if (cit->iItem == -1) { 875 876 875 COMBOEX_SetEditText (infoPtr, item); 876 RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | RDW_INVALIDATE); 877 877 } 878 878 return TRUE; … … 882 882 COMBOEX_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) 883 883 { 884 COMBOBOXEXITEMA 885 COMBOBOXEXITEMW 886 LRESULT 884 COMBOBOXEXITEMA *cit = (COMBOBOXEXITEMA *) lParam; 885 COMBOBOXEXITEMW citW; 886 LRESULT ret; 887 887 888 888 memcpy(&citW,cit,sizeof(COMBOBOXEXITEMA)); 889 889 if (cit->mask & CBEIF_TEXT) { 890 890 LPSTR str; 891 891 INT len; 892 892 893 893 str = cit->pszText; 894 894 if (!str) str=""; 895 896 897 898 899 895 len = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0); 896 if (len > 0) { 897 citW.pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR)); 898 MultiByteToWideChar (CP_ACP, 0, str, -1, citW.pszText, len); 899 } 900 900 } 901 901 ret = COMBOEX_SetItemW(hwnd,wParam,(LPARAM)&citW);; 902 902 903 903 if (cit->mask & CBEIF_TEXT) 904 904 COMCTL32_Free(citW.pszText); 905 905 return ret; 906 906 } … … 913 913 BOOL bTemp = infoPtr->bUnicode; 914 914 915 TRACE("to %s hwnd=0x%04x, was %s\n", 916 917 915 TRACE("to %s hwnd=0x%04x, was %s\n", 916 ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd, 917 (bTemp) ? "TRUE" : "FALSE"); 918 918 919 919 infoPtr->bUnicode = (BOOL)wParam; … … 937 937 i = MultiByteToWideChar (CP_ACP, 0, (LPSTR)lParam, -1, NULL, 0); 938 938 if (i > 0) { 939 940 939 desired = (LPWSTR)COMCTL32_Alloc ((i + 1)*sizeof(WCHAR)); 940 MultiByteToWideChar (CP_ACP, 0, (LPSTR)lParam, -1, desired, i); 941 941 } 942 942 … … 945 945 /* now search from after starting loc and wrapping back to start */ 946 946 for(i=start+1; i<count; i++) { 947 item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, 948 949 TRACE("desired=%s, item=%s\n", 950 951 952 953 954 947 item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, 948 CB_GETITEMDATA, (WPARAM)i, 0); 949 TRACE("desired=%s, item=%s\n", 950 debugstr_w(desired), debugstr_w(item->pszText)); 951 if (lstrcmpiW(item->pszText, desired) == 0) { 952 COMCTL32_Free (desired); 953 return i; 954 } 955 955 } 956 956 for(i=0; i<=start; i++) { 957 item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, 958 959 TRACE("desired=%s, item=%s\n", 960 961 962 963 964 957 item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, 958 CB_GETITEMDATA, (WPARAM)i, 0); 959 TRACE("desired=%s, item=%s\n", 960 debugstr_w(desired), debugstr_w(item->pszText)); 961 if (lstrcmpiW(item->pszText, desired) == 0) { 962 COMCTL32_Free (desired); 963 return i; 964 } 965 965 } 966 966 COMCTL32_Free(desired); … … 977 977 LRESULT lret = 0; 978 978 979 item1 = (CBE_ITEMDATA *)COMBOEX_Forward (hwnd, CB_GETITEMDATA, 980 979 item1 = (CBE_ITEMDATA *)COMBOEX_Forward (hwnd, CB_GETITEMDATA, 980 wParam, lParam); 981 981 if ((item1 != NULL) && ((LRESULT)item1 != CB_ERR)) { 982 983 984 985 986 987 988 989 990 982 item2 = COMBOEX_FindItem (infoPtr, index); 983 if (item2 != item1) { 984 ERR("data structures damaged!\n"); 985 return CB_ERR; 986 } 987 if (item1->mask & CBEIF_LPARAM) 988 lret = (LRESULT) item1->lParam; 989 TRACE("returning 0x%08lx\n", lret); 990 return lret; 991 991 } 992 992 lret = (LRESULT)item1; … … 1005 1005 1006 1006 if (!(item = COMBOEX_FindItem(infoPtr, index))) { 1007 1008 1007 /* FIXME: need to clear selection */ 1008 return CB_ERR; 1009 1009 } 1010 1010 1011 1011 TRACE("selecting item %d text=%s\n", index, (item->pszText) ? 1012 1012 debugstr_w(item->pszText) : "<null>"); 1013 1013 infoPtr->selected = index; 1014 1014 … … 1026 1026 CBE_ITEMDATA *item1, *item2; 1027 1027 1028 item1 = (CBE_ITEMDATA *)COMBOEX_Forward (hwnd, CB_GETITEMDATA, 1029 1028 item1 = (CBE_ITEMDATA *)COMBOEX_Forward (hwnd, CB_GETITEMDATA, 1029 wParam, lParam); 1030 1030 if ((item1 != NULL) && ((LRESULT)item1 != CB_ERR)) { 1031 1032 1033 1034 1035 1036 1037 1038 1039 1031 item2 = COMBOEX_FindItem (infoPtr, index); 1032 if (item2 != item1) { 1033 ERR("data structures damaged!\n"); 1034 return CB_ERR; 1035 } 1036 item1->mask |= CBEIF_LPARAM; 1037 item1->lParam = lParam; 1038 TRACE("setting lparam to 0x%08lx\n", lParam); 1039 return 0; 1040 1040 } 1041 1041 TRACE("non-valid result from combo 0x%08lx\n", (DWORD)item1); … … 1054 1054 /* First, lets forward the message to the normal combo control 1055 1055 just like Windows. */ 1056 if (infoPtr->hwndCombo) 1056 if (infoPtr->hwndCombo) 1057 1057 SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT, wParam, lParam); 1058 1058 … … 1060 1060 GetWindowRect (hwnd, &cbx_wrect); 1061 1061 GetClientRect (hwnd, &cbx_crect); 1062 /* the height of comboex as height of the combo + comboex border */ 1062 /* the height of comboex as height of the combo + comboex border */ 1063 1063 height = cb_wrect.bottom-cb_wrect.top 1064 1064 + cbx_wrect.bottom-cbx_wrect.top 1065 1065 - (cbx_crect.bottom-cbx_crect.top); 1066 1066 TRACE("EX window=(%d,%d)-(%d,%d), client=(%d,%d)-(%d,%d)\n", 1067 1068 1067 cbx_wrect.left, cbx_wrect.top, cbx_wrect.right, cbx_wrect.bottom, 1068 cbx_crect.left, cbx_crect.top, cbx_crect.right, cbx_crect.bottom); 1069 1069 TRACE("CB window=(%d,%d)-(%d,%d), EX setting=(0,0)-(%d,%d)\n", 1070 1071 1070 cb_wrect.left, cb_wrect.top, cb_wrect.right, cb_wrect.bottom, 1071 cbx_wrect.right-cbx_wrect.left, height); 1072 1072 SetWindowPos (hwnd, HWND_TOP, 0, 0, 1073 1074 1075 1073 cbx_wrect.right-cbx_wrect.left, 1074 height, 1075 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); 1076 1076 1077 1077 return ret; … … 1101 1101 #endif 1102 1102 if (infoPtr == NULL) { 1103 1104 1103 ERR("could not allocate info memory!\n"); 1104 return 0; 1105 1105 } 1106 1106 … … 1115 1115 1116 1116 i = SendMessageA(GetParent (hwnd), 1117 1117 WM_NOTIFYFORMAT, hwnd, NF_QUERY); 1118 1118 if ((i < NFR_ANSI) || (i > NFR_UNICODE)) { 1119 1120 1121 1119 ERR("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n", 1120 i); 1121 i = NFR_ANSI; 1122 1122 } 1123 1123 infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0; … … 1127 1127 /* create combo box */ 1128 1128 dwComboStyle = GetWindowLongA (hwnd, GWL_STYLE) & 1129 1129 (CBS_SIMPLE|CBS_DROPDOWN|CBS_DROPDOWNLIST|WS_CHILD); 1130 1130 1131 1131 GetWindowRect(hwnd, &wnrc1); 1132 1132 GetClientRect(hwnd, &clrc1); 1133 1133 TRACE("EX window=(%d,%d)-(%d,%d) client=(%d,%d)-(%d,%d)\n", 1134 1135 1134 wnrc1.left, wnrc1.top, wnrc1.right, wnrc1.bottom, 1135 clrc1.left, clrc1.top, clrc1.right, clrc1.bottom); 1136 1136 TRACE("combo style=%08lx, adding style=%08lx\n", dwComboStyle, 1137 1137 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL | 1138 1138 CBS_NOINTEGRALHEIGHT | CBS_DROPDOWNLIST | 1139 1139 WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED); 1140 1140 1141 1141 /* Native version of ComboEx creates the ComboBox with DROPDOWNLIST */ … … 1147 1147 1148 1148 infoPtr->hwndCombo = CreateWindowA ("ComboBox", "", 1149 1149 /* following line added to match native */ 1150 1150 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL | 1151 CBS_NOINTEGRALHEIGHT | CBS_DROPDOWNLIST | 1152 1153 1154 1155 1156 1157 1158 /* 1151 CBS_NOINTEGRALHEIGHT | CBS_DROPDOWNLIST | 1152 /* was base and is necessary */ 1153 WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED | dwComboStyle, 1154 cs->y, cs->x, cs->cx, cs->cy, hwnd, 1155 (HMENU) GetWindowLongA (hwnd, GWL_ID), 1156 GetWindowLongA (hwnd, GWL_HINSTANCE), NULL); 1157 1158 /* 1159 1159 * native does the following at this point according to trace: 1160 1160 * GetWindowThreadProcessId(hwndCombo,0) … … 1165 1165 1166 1166 /* 1167 * Setup a property to hold the pointer to the COMBOBOXEX 1167 * Setup a property to hold the pointer to the COMBOBOXEX 1168 1168 * data structure. 1169 1169 */ 1170 1170 test = GetPropA(infoPtr->hwndCombo, (LPCSTR)(LONG)ComboExInfo); 1171 1171 if (!test || ((COMBOEX_INFO *)test != infoPtr)) { 1172 1173 } 1174 infoPtr->prevComboWndProc = (WNDPROC)SetWindowLongA(infoPtr->hwndCombo, 1175 1172 SetPropA(infoPtr->hwndCombo, "CC32SubclassInfo", (LONG)infoPtr); 1173 } 1174 infoPtr->prevComboWndProc = (WNDPROC)SetWindowLongA(infoPtr->hwndCombo, 1175 GWL_WNDPROC, (LONG)COMBOEX_ComboWndProc); 1176 1176 infoPtr->font = SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0); 1177 1177 … … 1182 1182 */ 1183 1183 if ((cs->style & CBS_DROPDOWNLIST) == CBS_DROPDOWN) { 1184 1185 1186 1187 infoPtr->hwndCombo, 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 * Setup a property to hold the pointer to the COMBOBOXEX 1201 1202 1203 1204 1205 1206 1207 infoPtr->prevEditWndProc = (WNDPROC)SetWindowLongA(infoPtr->hwndEdit, 1208 1209 1184 infoPtr->hwndEdit = CreateWindowExA (0, "EDIT", "", 1185 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | ES_AUTOHSCROLL, 1186 0, 0, 0, 0, /* will set later */ 1187 infoPtr->hwndCombo, 1188 (HMENU) GetWindowLongA (hwnd, GWL_ID), 1189 GetWindowLongA (hwnd, GWL_HINSTANCE), 1190 NULL); 1191 1192 /* native does the following at this point according to trace: 1193 * GetWindowThreadProcessId(hwndEdit,0) 1194 * GetCurrentThreadId() 1195 * GetWindowThreadProcessId(hwndEdit, &???) 1196 * GetCurrentProcessId() 1197 */ 1198 1199 /* 1200 * Setup a property to hold the pointer to the COMBOBOXEX 1201 * data structure. 1202 */ 1203 test = GetPropA(infoPtr->hwndEdit, (LPCSTR)(LONG)ComboExInfo); 1204 if (!test || ((COMBOEX_INFO *)test != infoPtr)) { 1205 SetPropA(infoPtr->hwndEdit, "CC32SubclassInfo", (LONG)infoPtr); 1206 } 1207 infoPtr->prevEditWndProc = (WNDPROC)SetWindowLongA(infoPtr->hwndEdit, 1208 GWL_WNDPROC, (LONG)COMBOEX_EditWndProc); 1209 infoPtr->font = SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0); 1210 1210 } 1211 1211 else { 1212 1213 1212 infoPtr->hwndEdit = 0; 1213 infoPtr->font = 0; 1214 1214 } 1215 1215 … … 1219 1219 */ 1220 1220 if (!infoPtr->font) { 1221 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, sizeof(mylogfont), 1222 1223 1221 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, sizeof(mylogfont), 1222 &mylogfont, 0); 1223 infoPtr->font = CreateFontIndirectA (&mylogfont); 1224 1224 } 1225 1225 SendMessageW (infoPtr->hwndCombo, WM_SETFONT, (WPARAM)infoPtr->font, 0); 1226 1226 if (infoPtr->hwndEdit) { 1227 1228 1227 SendMessageW (infoPtr->hwndEdit, WM_SETFONT, (WPARAM)infoPtr->font, 0); 1228 SendMessageW (infoPtr->hwndEdit, EM_SETMARGINS, (WPARAM)EC_USEFONTINFO, 0); 1229 1229 } 1230 1230 … … 1237 1237 GetWindowRect(infoPtr->hwndCombo, &cmbwrc); 1238 1238 TRACE("EX window=(%d,%d)-(%d,%d) client=(%d,%d)-(%d,%d) CB wnd=(%d,%d)-(%d,%d)\n", 1239 1240 1241 1242 SetWindowPos(infoPtr->hwndCombo, HWND_TOP, 1243 1244 1239 wnrc1.left, wnrc1.top, wnrc1.right, wnrc1.bottom, 1240 clrc1.left, clrc1.top, clrc1.right, clrc1.bottom, 1241 cmbwrc.left, cmbwrc.top, cmbwrc.right, cmbwrc.bottom); 1242 SetWindowPos(infoPtr->hwndCombo, HWND_TOP, 1243 0, 0, wnrc1.right-wnrc1.left, wnrc1.bottom-wnrc1.top, 1244 SWP_NOACTIVATE | SWP_NOREDRAW); 1245 1245 1246 1246 GetWindowRect(infoPtr->hwndCombo, &cmbwrc); 1247 1247 TRACE("CB window=(%d,%d)-(%d,%d)\n", 1248 1249 SetWindowPos(hwnd, HWND_TOP, 1250 1251 1248 cmbwrc.left, cmbwrc.top, cmbwrc.right, cmbwrc.bottom); 1249 SetWindowPos(hwnd, HWND_TOP, 1250 0, 0, cmbwrc.right-cmbwrc.left, cmbwrc.bottom-cmbwrc.top, 1251 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); 1252 1252 1253 1253 COMBOEX_AdjustEditPos (infoPtr); 1254 1254 1255 1255 /* 1256 * Create an item structure to represent the data in the 1256 * Create an item structure to represent the data in the 1257 1257 * EDIT control. 1258 1258 */ … … 1284 1284 { 1285 1285 case CBN_DROPDOWN: 1286 SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 1287 1288 1289 * from native trace of first dropdown after typing in URL in IE4 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 * the rest is supposition 1300 1301 1302 1303 1304 1305 1306 1307 item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, 1308 CB_GETITEMDATA, 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, 1323 CB_GETITEMDATA, 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1286 SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 1287 (LPARAM)hwnd); 1288 /* 1289 * from native trace of first dropdown after typing in URL in IE4 1290 * CB_GETCURSEL(Combo) 1291 * GetWindowText(Edit) 1292 * CB_GETCURSEL(Combo) 1293 * CB_GETCOUNT(Combo) 1294 * CB_GETITEMDATA(Combo, n) 1295 * WM_NOTIFY(parent, CBEN_ENDEDITA|W) 1296 * CB_GETCURSEL(Combo) 1297 * CB_SETCURSEL(COMBOEX, n) 1298 * SetFocus(Combo) 1299 * the rest is supposition 1300 */ 1301 cursel = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0); 1302 if (cursel == -1) { 1303 /* find match from edit against those in Combobox */ 1304 GetWindowTextW (infoPtr->hwndEdit, wintext, 520); 1305 n = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0, 0); 1306 for (cursel = 0; cursel < n; cursel++){ 1307 item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, 1308 CB_GETITEMDATA, 1309 cursel, 0); 1310 if ((INT)item == CB_ERR) break; 1311 if (lstrcmpiW(item->pszText, wintext) == 0) break; 1312 } 1313 if ((cursel == n) || ((INT)item == CB_ERR)) { 1314 TRACE("failed to find match??? item=%p cursel=%d\n", 1315 item, cursel); 1316 if (infoPtr->hwndEdit) 1317 SetFocus(infoPtr->hwndEdit); 1318 return 0; 1319 } 1320 } 1321 else { 1322 item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, 1323 CB_GETITEMDATA, 1324 cursel, 0); 1325 if ((INT)item == CB_ERR) { 1326 TRACE("failed to find match??? item=%p cursel=%d\n", 1327 item, cursel); 1328 if (infoPtr->hwndEdit) 1329 SetFocus(infoPtr->hwndEdit); 1330 return 0; 1331 } 1332 } 1333 1334 /* Save flags for testing and reset them */ 1335 oldflags = infoPtr->flags; 1336 infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG); 1337 1338 if (oldflags & WCBE_ACTEDIT) { 1339 cbeend.fChanged = (oldflags & WCBE_EDITCHG); 1340 cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo, 1341 CB_GETCURSEL, 0, 0); 1342 cbeend.iWhy = CBENF_DROPDOWN; 1343 1344 if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, item->pszText)) { 1345 /* abort the change */ 1346 TRACE("Notify requested abort of change\n"); 1347 return 0; 1348 } 1349 } 1350 1351 /* if selection has changed the set the new current selection */ 1352 cursel = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0); 1353 if ((oldflags & WCBE_EDITCHG) || (cursel != infoPtr->selected)) { 1354 infoPtr->selected = cursel; 1355 SendMessageW (hwnd, CB_SETCURSEL, cursel, 0); 1356 SetFocus(infoPtr->hwndCombo); 1357 } 1358 return 0; 1359 1359 1360 1360 case CBN_SELCHANGE: 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 return SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 1382 1361 /* 1362 * CB_GETCURSEL(Combo) 1363 * CB_GETITEMDATA(Combo) < simulated by COMBOEX_FindItem 1364 * lstrlenA 1365 * WM_SETTEXT(Edit) 1366 * WM_GETTEXTLENGTH(Edit) 1367 * WM_GETTEXT(Edit) 1368 * EM_SETSEL(Edit, 0,0) 1369 * WM_GETTEXTLENGTH(Edit) 1370 * WM_GETTEXT(Edit) 1371 * EM_SETSEL(Edit, 0,len) 1372 * return WM_COMMAND to parent 1373 */ 1374 oldItem = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0); 1375 if (!(item = COMBOEX_FindItem(infoPtr, oldItem))) { 1376 ERR("item %d not found. Problem!\n", oldItem); 1377 break; 1378 } 1379 infoPtr->selected = oldItem; 1380 COMBOEX_SetEditText (infoPtr, item); 1381 return SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 1382 (LPARAM)hwnd); 1383 1383 1384 1384 case CBN_SELENDOK: 1385 /* 1386 1387 1388 1389 return SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 1390 1385 /* 1386 * We have to change the handle since we are the control 1387 * issuing the message. IE4 depends on this. 1388 */ 1389 return SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 1390 (LPARAM)hwnd); 1391 1391 1392 1392 case CBN_KILLFOCUS: 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1393 /* 1394 * from native trace: 1395 * 1396 * pass to parent 1397 * WM_GETTEXT(Edit, 104) 1398 * CB_GETCURSEL(Combo) rets -1 1399 * WM_NOTIFY(CBEN_ENDEDITA) with CBENF_KILLFOCUS 1400 * CB_GETCURSEL(Combo) 1401 * InvalidateRect(Combo, 0, 0) 1402 * return 0 1403 */ 1404 SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 1405 (LPARAM)hwnd); 1406 if (infoPtr->flags & WCBE_ACTEDIT) { 1407 GetWindowTextW (infoPtr->hwndEdit, wintext, 260); 1408 cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG); 1409 cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo, 1410 CB_GETCURSEL, 0, 0); 1411 cbeend.iWhy = CBENF_KILLFOCUS; 1412 1413 infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG); 1414 if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, wintext)) { 1415 /* abort the change */ 1416 TRACE("Notify requested abort of change\n"); 1417 return 0; 1418 } 1419 } 1420 /* possible CB_GETCURSEL */ 1421 InvalidateRect (infoPtr->hwndCombo, 0, 0); 1422 return 0; 1423 1423 1424 1424 case CBN_CLOSEUP: 1425 1425 default: 1426 /* 1427 1428 1429 1430 1431 1432 lret = SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 1433 1434 1435 1436 1426 /* 1427 * We have to change the handle since we are the control 1428 * issuing the message. IE4 depends on this. 1429 * We also need to set the focus back to the Edit control 1430 * after passing the command to the parent of the ComboEx. 1431 */ 1432 lret = SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 1433 (LPARAM)hwnd); 1434 if (infoPtr->hwndEdit) 1435 SetFocus(infoPtr->hwndEdit); 1436 return lret; 1437 1437 } 1438 1438 return 0; … … 1450 1450 1451 1451 TRACE("CtlType=%08x, CtlID=%08x, itemID=%08x, hwnd=%x, data=%08lx\n", 1452 1452 dis->CtlType, dis->CtlID, dis->itemID, dis->hwndItem, dis->itemData); 1453 1453 1454 1454 if ((dis->itemID >= infoPtr->nb_items) || (dis->itemID < 0)) return FALSE; … … 1458 1458 1459 1459 if (i == dis->itemID) { 1460 1460 infoPtr->items = infoPtr->items->next; 1461 1461 } 1462 1462 else { 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1463 item = olditem; 1464 i--; 1465 1466 /* find the prior item in the list */ 1467 while (item->next && (i > dis->itemID)) { 1468 item = (CBE_ITEMDATA *)item->next; 1469 i--; 1470 } 1471 if (!item->next || (i != dis->itemID)) { 1472 FIXME("COMBOBOXEX item structures broken. Please report!\n"); 1473 return FALSE; 1474 } 1475 olditem = item->next; 1476 item->next = (CBE_ITEMDATA *)((CBE_ITEMDATA *)item->next)->next; 1477 1477 } 1478 1478 infoPtr->nb_items--; … … 1482 1482 1483 1483 if (olditem->pszText) 1484 1484 COMCTL32_Free(olditem->pszText); 1485 1485 COMCTL32_Free(olditem); 1486 1486 … … 1510 1510 /* dump the DRAWITEMSTRUCT if tracing "comboex" but not "message" */ 1511 1511 if (!TRACE_ON(message)) { 1512 TRACE("DRAWITEMSTRUCT: CtlType=0x%08x CtlID=0x%08x\n", 1513 1514 TRACE("itemID=0x%08x itemAction=0x%08x itemState=0x%08x\n", 1515 1516 1517 dis->hwndItem, dis->hDC, dis->rcItem.left, 1518 dis->rcItem.top, dis->rcItem.right, dis->rcItem.bottom, 1519 1512 TRACE("DRAWITEMSTRUCT: CtlType=0x%08x CtlID=0x%08x\n", 1513 dis->CtlType, dis->CtlID); 1514 TRACE("itemID=0x%08x itemAction=0x%08x itemState=0x%08x\n", 1515 dis->itemID, dis->itemAction, dis->itemState); 1516 TRACE("hWnd=0x%04x hDC=0x%04x (%d,%d)-(%d,%d) itemData=0x%08lx\n", 1517 dis->hwndItem, dis->hDC, dis->rcItem.left, 1518 dis->rcItem.top, dis->rcItem.right, dis->rcItem.bottom, 1519 dis->itemData); 1520 1520 } 1521 1521 … … 1532 1532 /* though the list box or combo box has the focus. */ 1533 1533 if (dis->itemID == 0xffffffff) { 1534 1535 ( (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) && (dis->itemState & ODS_FOCUS) ) ) { 1536 1537 1538 1539 1540 1541 else if ((dis->CtlType == ODT_COMBOBOX) && 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1534 if ( ( (dis->itemAction & ODA_FOCUS) && (dis->itemState & ODS_SELECTED)) || 1535 ( (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) && (dis->itemState & ODS_FOCUS) ) ) { 1536 1537 TRACE("drawing item -1 special focus, rect=(%d,%d)-(%d,%d)\n", 1538 dis->rcItem.left, dis->rcItem.top, 1539 dis->rcItem.right, dis->rcItem.bottom); 1540 } 1541 else if ((dis->CtlType == ODT_COMBOBOX) && 1542 (dis->itemAction == ODA_DRAWENTIRE)) { 1543 /* draw of edit control data */ 1544 1545 /* testing */ 1546 { 1547 RECT exrc, cbrc, edrc; 1548 GetWindowRect (hwnd, &exrc); 1549 GetWindowRect (infoPtr->hwndCombo, &cbrc); 1550 edrc.left=edrc.top=edrc.right=edrc.bottom=-1; 1551 if (infoPtr->hwndEdit) 1552 GetWindowRect (infoPtr->hwndEdit, &edrc); 1553 TRACE("window rects ex=(%d,%d)-(%d,%d), cb=(%d,%d)-(%d,%d), ed=(%d,%d)-(%d,%d)\n", 1554 exrc.left, exrc.top, exrc.right, exrc.bottom, 1555 cbrc.left, cbrc.top, cbrc.right, cbrc.bottom, 1556 edrc.left, edrc.top, edrc.right, edrc.bottom); 1557 } 1558 } 1559 else { 1560 ERR("NOT drawing item -1 special focus, rect=(%d,%d)-(%d,%d), action=%08x, state=%08x\n", 1561 dis->rcItem.left, dis->rcItem.top, 1562 dis->rcItem.right, dis->rcItem.bottom, 1563 dis->itemAction, dis->itemState); 1564 return 0; 1565 } 1566 1566 } 1567 1567 1568 1568 /* If draw item is -1 (edit control) setup the item pointer */ 1569 1569 if (dis->itemID == 0xffffffff) { 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1570 CHAR str[260]; 1571 INT wlen, alen; 1572 1573 item = infoPtr->edit; 1574 1575 if (infoPtr->hwndEdit) { 1576 1577 /* free previous text of edit item */ 1578 if (item->pszText) { 1579 COMCTL32_Free(item->pszText); 1580 item->pszText = 0; 1581 item->mask &= ~CBEIF_TEXT; 1582 } 1583 alen = SendMessageA (infoPtr->hwndEdit, WM_GETTEXT, 260, (LPARAM)&str); 1584 TRACE("edit control hwndEdit=%0x, text len=%d str=<%s>\n", 1585 infoPtr->hwndEdit, alen, str); 1586 if (alen > 0) { 1587 item->mask |= CBEIF_TEXT; 1588 wlen = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0); 1589 if (wlen > 0) { 1590 item->pszText = (LPWSTR)COMCTL32_Alloc ((wlen + 1)*sizeof(WCHAR)); 1591 MultiByteToWideChar (CP_ACP, 0, str, -1, item->pszText, wlen); 1592 } 1593 } 1594 } 1595 1595 } 1596 1596 1597 1597 /* if the item pointer is not set, then get the data and locate it */ 1598 1598 if (!item) { 1599 1600 1601 1602 1603 1604 1605 1599 item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, 1600 CB_GETITEMDATA, (WPARAM)dis->itemID, 0); 1601 if (item == (CBE_ITEMDATA *)CB_ERR) 1602 { 1603 FIXME("invalid item for id %d \n",dis->itemID); 1604 return 0; 1605 } 1606 1606 } 1607 1607 … … 1612 1612 xbase += (item->iIndent * CBE_INDENT); 1613 1613 if (item->mask & CBEIF_IMAGE) { 1614 1615 1614 ImageList_GetImageInfo(infoPtr->himl, item->iImage, &iinfo); 1615 xioff = (iinfo.rcImage.right - iinfo.rcImage.left + CBE_SEP); 1616 1616 } 1617 1617 … … 1619 1619 case ODA_FOCUS: 1620 1620 if (dis->itemState & ODS_SELECTED /*1*/) { 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1621 if ((item->mask & CBEIF_TEXT) && item->pszText) { 1622 RECT rect2; 1623 1624 len = strlenW (item->pszText); 1625 GetTextExtentPointW (dis->hDC, item->pszText, len, &txtsize); 1626 rect.left = xbase + xioff - 1; 1627 rect.right = rect.left + txtsize.cx + 2; 1628 rect.top = dis->rcItem.top; 1629 rect.bottom = dis->rcItem.bottom; 1630 GetClipBox (dis->hDC, &rect2); 1631 TRACE("drawing item %d focus, rect=(%d,%d)-(%d,%d)\n", 1632 dis->itemID, rect.left, rect.top, 1633 rect.right, rect.bottom); 1634 TRACE(" clip=(%d,%d)-(%d,%d)\n", 1635 rect2.left, rect2.top, 1636 rect2.right, rect2.bottom); 1637 1638 DrawFocusRect(dis->hDC, &rect); 1639 } 1640 else { 1641 FIXME("ODA_FOCUS and ODS_SELECTED but no text\n"); 1642 } 1643 } 1644 else { 1645 FIXME("ODA_FOCUS but not ODS_SELECTED\n"); 1646 } 1647 1647 break; 1648 1648 case ODA_SELECT: 1649 1649 case ODA_DRAWENTIRE: 1650 1650 drawimage = -1; 1651 1652 1653 if (item->mask & CBEIF_IMAGE) 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 /* if we have an edit control, the slave the 1667 * selection state to the Edit focus state 1668 1669 1670 1671 1672 1673 1674 1675 1676 /* if we don't have an edit control, use 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 ImageList_Draw (infoPtr->himl, drawimage, dis->hDC, 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1651 drawstate = ILD_NORMAL; 1652 if (!(infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE)) { 1653 if (item->mask & CBEIF_IMAGE) 1654 drawimage = item->iImage; 1655 if (dis->itemState & ODS_COMBOEXLBOX) { 1656 /* drawing listbox entry */ 1657 if (dis->itemState & ODS_SELECTED) { 1658 if (item->mask & CBEIF_SELECTEDIMAGE) 1659 drawimage = item->iSelectedImage; 1660 drawstate = ILD_SELECTED; 1661 } 1662 } 1663 else { 1664 /* drawing combo/edit entry */ 1665 if (infoPtr->hwndEdit) { 1666 /* if we have an edit control, the slave the 1667 * selection state to the Edit focus state 1668 */ 1669 if (infoPtr->flags & WCBE_EDITFOCUSED) { 1670 if (item->mask & CBEIF_SELECTEDIMAGE) 1671 drawimage = item->iSelectedImage; 1672 drawstate = ILD_SELECTED; 1673 } 1674 } 1675 else { 1676 /* if we don't have an edit control, use 1677 * the requested state. 1678 */ 1679 if (dis->itemState & ODS_SELECTED) { 1680 if (item->mask & CBEIF_SELECTEDIMAGE) 1681 drawimage = item->iSelectedImage; 1682 drawstate = ILD_SELECTED; 1683 } 1684 } 1685 } 1686 } 1687 if (drawimage != -1) { 1688 TRACE("drawing image state=%d\n", dis->itemState & ODS_SELECTED); 1689 ImageList_Draw (infoPtr->himl, drawimage, dis->hDC, 1690 xbase, dis->rcItem.top, drawstate); 1691 } 1692 1693 /* setup pointer to text to be drawn */ 1694 if ((item->mask & CBEIF_TEXT) && item->pszText) 1695 str = item->pszText; 1696 else 1697 str = (LPWSTR) L""; 1698 1699 /* now draw the text */ 1700 len = lstrlenW (str); 1701 GetTextExtentPointW (dis->hDC, str, len, &txtsize); 1702 nbkc = GetSysColor ((dis->itemState & ODS_SELECTED) ? 1703 COLOR_HIGHLIGHT : COLOR_WINDOW); 1704 SetBkColor (dis->hDC, nbkc); 1705 ntxc = GetSysColor ((dis->itemState & ODS_SELECTED) ? 1706 COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT); 1707 SetTextColor (dis->hDC, ntxc); 1708 x = xbase + xioff; 1709 y = dis->rcItem.top + 1710 (dis->rcItem.bottom - dis->rcItem.top - txtsize.cy) / 2; 1711 rect.left = x; 1712 rect.right = x + txtsize.cx; 1713 rect.top = dis->rcItem.top + 1; 1714 rect.bottom = dis->rcItem.bottom - 1; 1715 TRACE("drawing item %d text, rect=(%d,%d)-(%d,%d)\n", 1716 dis->itemID, rect.left, rect.top, rect.right, rect.bottom); 1717 ExtTextOutW (dis->hDC, x, y, ETO_OPAQUE | ETO_CLIPPED, 1718 &rect, str, len, 0); 1719 if (dis->itemState & ODS_FOCUS) { 1720 rect.top -= 1; 1721 rect.bottom += 1; 1722 rect.left -= 1; 1723 rect.right += 1; 1724 TRACE("drawing item %d focus after text, rect=(%d,%d)-(%d,%d)\n", 1725 dis->itemID, rect.left, rect.top, rect.right, rect.bottom); 1726 DrawFocusRect (dis->hDC, &rect); 1727 } 1728 break; 1729 1729 default: 1730 FIXME("unknown action hwnd=%08x, wparam=%08x, lparam=%08lx, action=%d\n", 1731 1730 FIXME("unknown action hwnd=%08x, wparam=%08x, lparam=%08lx, action=%d\n", 1731 hwnd, wParam, lParam, dis->itemAction); 1732 1732 } 1733 1733 … … 1742 1742 1743 1743 if (infoPtr->hwndCombo) 1744 1744 DestroyWindow (infoPtr->hwndCombo); 1745 1745 1746 1746 if (infoPtr->edit) { 1747 1748 1747 COMCTL32_Free (infoPtr->edit); 1748 infoPtr->edit = 0; 1749 1749 } 1750 1750 … … 1752 1752 CBE_ITEMDATA *this, *next; 1753 1753 1754 1755 1756 1757 1758 1759 1760 1761 1754 this = infoPtr->items; 1755 while (this) { 1756 next = (CBE_ITEMDATA *)this->next; 1757 if ((this->mask & CBEIF_TEXT) && this->pszText) 1758 COMCTL32_Free (this->pszText); 1759 COMCTL32_Free (this); 1760 this = next; 1761 } 1762 1762 } 1763 1763 … … 1785 1785 1786 1786 TRACE("adjusted height hwnd=%08x, height=%d\n", 1787 1787 hwnd, mis->itemHeight); 1788 1788 1789 1789 return 0; … … 1800 1800 newstyle = oldstyle & ~(WS_VSCROLL | WS_HSCROLL); 1801 1801 if (newstyle != oldstyle) { 1802 1803 1804 1802 TRACE("req style %08lx, reseting style %08lx\n", 1803 oldstyle, newstyle); 1804 SetWindowLongA (hwnd, GWL_STYLE, newstyle); 1805 1805 } 1806 1806 return 1; … … 1815 1815 1816 1816 if (lParam == NF_REQUERY) { 1817 1818 1819 1820 1821 1822 1823 1824 1825 1817 i = SendMessageA(GetParent (hwnd), 1818 WM_NOTIFYFORMAT, infoPtr->hwndSelf, NF_QUERY); 1819 if ((i < NFR_ANSI) || (i > NFR_UNICODE)) { 1820 ERR("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n", 1821 i); 1822 i = NFR_ANSI; 1823 } 1824 infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0; 1825 return (LRESULT)i; 1826 1826 } 1827 1827 return (LRESULT)((infoPtr->bUnicode) ? NFR_UNICODE : NFR_ANSI); … … 1837 1837 GetWindowRect (hwnd, &rect); 1838 1838 TRACE("my rect (%d,%d)-(%d,%d)\n", 1839 1839 rect.left, rect.top, rect.right, rect.bottom); 1840 1840 1841 1841 MoveWindow (infoPtr->hwndCombo, 0, 0, rect.right -rect.left, 1842 1842 rect.bottom - rect.top, TRUE); 1843 1843 1844 1844 COMBOEX_AdjustEditPos (infoPtr); … … 1862 1862 /* width is winpos value + border width of comboex */ 1863 1863 width = wp->cx 1864 + (cbx_wrect.right-cbx_wrect.left) 1865 - (cbx_crect.right-cbx_crect.left); 1864 + (cbx_wrect.right-cbx_wrect.left) 1865 - (cbx_crect.right-cbx_crect.left); 1866 1866 1867 1867 TRACE("winpos=(%d,%d %dx%d) flags=0x%08x\n", 1868 1868 wp->x, wp->y, wp->cx, wp->cy, wp->flags); 1869 1869 TRACE("EX window=(%d,%d)-(%d,%d), client=(%d,%d)-(%d,%d)\n", 1870 1871 1870 cbx_wrect.left, cbx_wrect.top, cbx_wrect.right, cbx_wrect.bottom, 1871 cbx_crect.left, cbx_crect.top, cbx_crect.right, cbx_crect.bottom); 1872 1872 TRACE("CB window=(%d,%d)-(%d,%d), EX setting=(0,0)-(%d,%d)\n", 1873 1874 1873 cb_wrect.left, cb_wrect.top, cb_wrect.right, cb_wrect.bottom, 1874 width, cb_wrect.bottom-cb_wrect.top); 1875 1875 1876 1876 if (width) SetWindowPos (infoPtr->hwndCombo, HWND_TOP, 0, 0, 1877 1878 1879 1877 width, 1878 cb_wrect.bottom-cb_wrect.top, 1879 SWP_NOACTIVATE); 1880 1880 1881 1881 GetWindowRect (infoPtr->hwndCombo, &cb_wrect); … … 1883 1883 /* height is combo window height plus border width of comboex */ 1884 1884 height = (cb_wrect.bottom-cb_wrect.top) 1885 1885 + (cbx_wrect.bottom-cbx_wrect.top) 1886 1886 - (cbx_crect.bottom-cbx_crect.top); 1887 1887 if (wp->cy < height) wp->cy = height; 1888 1888 if (infoPtr->hwndEdit) { 1889 1890 1889 COMBOEX_AdjustEditPos (infoPtr); 1890 InvalidateRect (infoPtr->hwndCombo, 0, TRUE); 1891 1891 } 1892 1892 … … 1906 1906 LRESULT lret; 1907 1907 1908 TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx, info_ptr=%p\n", 1909 1908 TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx, info_ptr=%p\n", 1909 hwnd, uMsg, wParam, lParam, infoPtr); 1910 1910 1911 1911 if (!infoPtr) return 0; … … 1915 1915 1916 1916 case WM_CHAR: 1917 1918 1919 1920 return CallWindowProcA (infoPtr->prevEditWndProc, 1921 1917 /* handle (ignore) the return character */ 1918 if (wParam == VK_RETURN) return 0; 1919 /* all other characters pass into the real Edit */ 1920 return CallWindowProcA (infoPtr->prevEditWndProc, 1921 hwnd, uMsg, wParam, lParam); 1922 1922 1923 1923 case WM_ERASEBKGND: 1924 1925 * The following was determined by traces of the native 1926 1924 /* 1925 * The following was determined by traces of the native 1926 */ 1927 1927 hDC = (HDC) wParam; 1928 1929 1928 nbkc = GetSysColor (COLOR_WINDOW); 1929 obkc = SetBkColor (hDC, nbkc); 1930 1930 GetClientRect (hwnd, &rect); 1931 1932 1933 1931 TRACE("erasing (%d,%d)-(%d,%d)\n", 1932 rect.left, rect.top, rect.right, rect.bottom); 1933 ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0); 1934 1934 SetBkColor (hDC, obkc); 1935 return CallWindowProcA (infoPtr->prevEditWndProc, 1936 1935 return CallWindowProcA (infoPtr->prevEditWndProc, 1936 hwnd, uMsg, wParam, lParam); 1937 1937 1938 1938 case WM_KEYDOWN: { 1939 INT oldItem, selected; 1940 CBE_ITEMDATA *item; 1941 1942 switch ((INT)wParam) 1943 { 1944 case VK_ESCAPE: 1945 /* native version seems to do following for COMBOEX */ 1946 /* 1947 * GetWindowTextA(Edit,&?, 0x104) x 1948 * CB_GETCURSEL to Combo rets -1 x 1949 * WM_NOTIFY to COMBOEX parent (rebar) x 1950 * (CBEN_ENDEDIT{A|W} 1951 * fChanged = FALSE x 1952 * inewSelection = -1 x 1953 * txt="www.hoho" x 1954 * iWhy = 3 x 1955 * CB_GETCURSEL to Combo rets -1 x 1956 * InvalidateRect(Combo, 0) x 1957 * WM_SETTEXT to Edit x 1958 * EM_SETSEL to Edit (0,0) x 1959 * EM_SETSEL to Edit (0,-1) x 1960 * RedrawWindow(Combo, 0, 0, 5) x 1961 */ 1962 TRACE("special code for VK_ESCAPE\n"); 1963 1964 GetWindowTextW (infoPtr->hwndEdit, edit_text, 260); 1965 1966 infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG); 1967 cbeend.fChanged = FALSE; 1968 cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo, 1969 CB_GETCURSEL, 0, 0); 1970 cbeend.iWhy = CBENF_ESCAPE; 1971 1972 if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) { 1973 /* abort the change */ 1974 TRACE("Notify requested abort of change\n"); 1975 return 0; 1976 } 1977 oldItem = SendMessageW (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0); 1978 InvalidateRect (infoPtr->hwndCombo, 0, 0); 1979 if (!(item = COMBOEX_FindItem(infoPtr, oldItem))) { 1980 ERR("item %d not found. Problem!\n", oldItem); 1981 break; 1982 } 1983 infoPtr->selected = oldItem; 1984 COMBOEX_SetEditText (infoPtr, item); 1985 RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | 1986 RDW_INVALIDATE); 1987 break; 1988 1989 case VK_RETURN: 1990 /* native version seems to do following for COMBOEX */ 1991 /* 1992 * GetWindowTextA(Edit,&?, 0x104) x 1993 * CB_GETCURSEL to Combo rets -1 x 1994 * CB_GETCOUNT to Combo rets 0 1995 * if >0 loop 1996 * CB_GETITEMDATA to match 1997 * *** above 3 lines simulated by FindItem x 1998 * WM_NOTIFY to COMBOEX parent (rebar) x 1999 * (CBEN_ENDEDIT{A|W} x 2000 * fChanged = TRUE (-1) x 2001 * iNewSelection = -1 or selected x 2002 * txt= x 2003 * iWhy = 2 (CBENF_RETURN) x 2004 * CB_GETCURSEL to Combo rets -1 x 2005 * if -1 send CB_SETCURSEL to Combo -1 x 2006 * InvalidateRect(Combo, 0, 0) x 2007 * SetFocus(Edit) x 2008 * CallWindowProc(406615a8, Edit, 0x100, 0xd, 0x1c0001) 2009 */ 2010 2011 TRACE("special code for VK_RETURN\n"); 2012 2013 GetWindowTextW (infoPtr->hwndEdit, edit_text, 260); 2014 2015 infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG); 2016 selected = SendMessageW (infoPtr->hwndCombo, 2017 CB_GETCURSEL, 0, 0); 2018 2019 if (selected != -1) { 2020 item = COMBOEX_FindItem (infoPtr, selected); 2021 TRACE("handling VK_RETURN, selected = %d, selected_text=%s\n", 2022 selected, debugstr_w(item->pszText)); 2023 TRACE("handling VK_RETURN, edittext=%s\n", 2024 debugstr_w(edit_text)); 2025 if (lstrcmpiW (item->pszText, edit_text)) { 2026 /* strings not equal -- indicate edit has changed */ 2027 selected = -1; 1939 INT oldItem, selected; 1940 CBE_ITEMDATA *item; 1941 1942 switch ((INT)wParam) 1943 { 1944 case VK_ESCAPE: 1945 /* native version seems to do following for COMBOEX */ 1946 /* 1947 * GetWindowTextA(Edit,&?, 0x104) x 1948 * CB_GETCURSEL to Combo rets -1 x 1949 * WM_NOTIFY to COMBOEX parent (rebar) x 1950 * (CBEN_ENDEDIT{A|W} 1951 * fChanged = FALSE x 1952 * inewSelection = -1 x 1953 * txt="www.hoho" x 1954 * iWhy = 3 x 1955 * CB_GETCURSEL to Combo rets -1 x 1956 * InvalidateRect(Combo, 0) x 1957 * WM_SETTEXT to Edit x 1958 * EM_SETSEL to Edit (0,0) x 1959 * EM_SETSEL to Edit (0,-1) x 1960 * RedrawWindow(Combo, 0, 0, 5) x 1961 */ 1962 TRACE("special code for VK_ESCAPE\n"); 1963 1964 GetWindowTextW (infoPtr->hwndEdit, edit_text, 260); 1965 1966 infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG); 1967 cbeend.fChanged = FALSE; 1968 cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo, 1969 CB_GETCURSEL, 0, 0); 1970 cbeend.iWhy = CBENF_ESCAPE; 1971 1972 if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) { 1973 /* abort the change */ 1974 TRACE("Notify requested abort of change\n"); 1975 return 0; 1976 } 1977 oldItem = SendMessageW (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0); 1978 InvalidateRect (infoPtr->hwndCombo, 0, 0); 1979 if (!(item = COMBOEX_FindItem(infoPtr, oldItem))) { 1980 ERR("item %d not found. Problem!\n", oldItem); 1981 break; 1982 } 1983 infoPtr->selected = oldItem; 1984 COMBOEX_SetEditText (infoPtr, item); 1985 RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | 1986 RDW_INVALIDATE); 1987 break; 1988 1989 case VK_RETURN: 1990 /* native version seems to do following for COMBOEX */ 1991 /* 1992 * GetWindowTextA(Edit,&?, 0x104) x 1993 * CB_GETCURSEL to Combo rets -1 x 1994 * CB_GETCOUNT to Combo rets 0 1995 * if >0 loop 1996 * CB_GETITEMDATA to match 1997 * *** above 3 lines simulated by FindItem x 1998 * WM_NOTIFY to COMBOEX parent (rebar) x 1999 * (CBEN_ENDEDIT{A|W} x 2000 * fChanged = TRUE (-1) x 2001 * iNewSelection = -1 or selected x 2002 * txt= x 2003 * iWhy = 2 (CBENF_RETURN) x 2004 * CB_GETCURSEL to Combo rets -1 x 2005 * if -1 send CB_SETCURSEL to Combo -1 x 2006 * InvalidateRect(Combo, 0, 0) x 2007 * SetFocus(Edit) x 2008 * CallWindowProc(406615a8, Edit, 0x100, 0xd, 0x1c0001) 2009 */ 2010 2011 TRACE("special code for VK_RETURN\n"); 2012 2013 GetWindowTextW (infoPtr->hwndEdit, edit_text, 260); 2014 2015 infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG); 2016 selected = SendMessageW (infoPtr->hwndCombo, 2017 CB_GETCURSEL, 0, 0); 2018 2019 if (selected != -1) { 2020 item = COMBOEX_FindItem (infoPtr, selected); 2021 TRACE("handling VK_RETURN, selected = %d, selected_text=%s\n", 2022 selected, debugstr_w(item->pszText)); 2023 TRACE("handling VK_RETURN, edittext=%s\n", 2024 debugstr_w(edit_text)); 2025 if (lstrcmpiW (item->pszText, edit_text)) { 2026 /* strings not equal -- indicate edit has changed */ 2027 selected = -1; 2028 } 2029 } 2030 2031 cbeend.iNewSelection = selected; 2032 cbeend.fChanged = TRUE; 2033 cbeend.iWhy = CBENF_RETURN; 2034 if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) { 2035 /* abort the change, restore previous */ 2036 TRACE("Notify requested abort of change\n"); 2037 COMBOEX_SetEditText (infoPtr, infoPtr->edit); 2038 RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | 2039 RDW_INVALIDATE); 2040 return 0; 2041 } 2042 oldItem = SendMessageW (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0); 2043 if (oldItem != -1) { 2044 /* if something is selected, then deselect it */ 2045 SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, 2046 (WPARAM)-1, 0); 2047 } 2048 InvalidateRect (infoPtr->hwndCombo, 0, 0); 2049 SetFocus(infoPtr->hwndEdit); 2050 break; 2051 2052 default: 2053 return CallWindowProcA (infoPtr->prevEditWndProc, 2054 hwnd, uMsg, wParam, lParam); 2055 } 2056 return 0; 2028 2057 } 2029 }2030 2031 cbeend.iNewSelection = selected;2032 cbeend.fChanged = TRUE;2033 cbeend.iWhy = CBENF_RETURN;2034 if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) {2035 /* abort the change, restore previous */2036 TRACE("Notify requested abort of change\n");2037 COMBOEX_SetEditText (infoPtr, infoPtr->edit);2038 RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE |2039 RDW_INVALIDATE);2040 return 0;2041 }2042 oldItem = SendMessageW (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0);2043 if (oldItem != -1) {2044 /* if something is selected, then deselect it */2045 SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL,2046 (WPARAM)-1, 0);2047 }2048 InvalidateRect (infoPtr->hwndCombo, 0, 0);2049 SetFocus(infoPtr->hwndEdit);2050 break;2051 2052 default:2053 return CallWindowProcA (infoPtr->prevEditWndProc,2054 hwnd, uMsg, wParam, lParam);2055 }2056 return 0;2057 }2058 2058 2059 2059 case WM_SETFOCUS: 2060 2061 lret = CallWindowProcA (infoPtr->prevEditWndProc, 2062 2063 2064 2060 /* remember the focus to set state of icon */ 2061 lret = CallWindowProcA (infoPtr->prevEditWndProc, 2062 hwnd, uMsg, wParam, lParam); 2063 infoPtr->flags |= WCBE_EDITFOCUSED; 2064 return lret; 2065 2065 2066 2066 case WM_KILLFOCUS: 2067 /* 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2067 /* 2068 * do NOTIFY CBEN_ENDEDIT with CBENF_KILLFOCUS 2069 */ 2070 infoPtr->flags &= ~WCBE_EDITFOCUSED; 2071 if (infoPtr->flags & WCBE_ACTEDIT) { 2072 infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG); 2073 2074 GetWindowTextW (infoPtr->hwndEdit, edit_text, 260); 2075 cbeend.fChanged = FALSE; 2076 cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo, 2077 CB_GETCURSEL, 0, 0); 2078 cbeend.iWhy = CBENF_KILLFOCUS; 2079 2080 COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text); 2081 } 2082 /* fall through */ 2083 2083 2084 2084 default: 2085 return CallWindowProcA (infoPtr->prevEditWndProc, 2086 2085 return CallWindowProcA (infoPtr->prevEditWndProc, 2086 hwnd, uMsg, wParam, lParam); 2087 2087 } 2088 2088 return 0; … … 2102 2102 WCHAR edit_text[260]; 2103 2103 2104 TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx, info_ptr=%p\n", 2105 2104 TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx, info_ptr=%p\n", 2105 hwnd, uMsg, wParam, lParam, infoPtr); 2106 2106 2107 2107 if (!infoPtr) return 0; … … 2111 2111 2112 2112 case CB_FINDSTRINGEXACT: 2113 2113 return COMBOEX_FindStringExact (infoPtr, wParam, lParam); 2114 2114 2115 2115 case WM_DRAWITEM: 2116 2117 2118 2119 2120 2121 2122 return CallWindowProcA (infoPtr->prevComboWndProc, 2123 2116 /* 2117 * The only way this message should come is from the 2118 * child Listbox issuing the message. Flag this so 2119 * that ComboEx knows this is listbox. 2120 */ 2121 ((DRAWITEMSTRUCT *)lParam)->itemState |= ODS_COMBOEXLBOX; 2122 return CallWindowProcA (infoPtr->prevComboWndProc, 2123 hwnd, uMsg, wParam, lParam); 2124 2124 2125 2125 case WM_ERASEBKGND: 2126 2127 * The following was determined by traces of the native 2128 2126 /* 2127 * The following was determined by traces of the native 2128 */ 2129 2129 hDC = (HDC) wParam; 2130 2131 2130 nbkc = GetSysColor (COLOR_WINDOW); 2131 obkc = SetBkColor (hDC, nbkc); 2132 2132 GetClientRect (hwnd, &rect); 2133 2134 2135 2133 TRACE("erasing (%d,%d)-(%d,%d)\n", 2134 rect.left, rect.top, rect.right, rect.bottom); 2135 ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0); 2136 2136 SetBkColor (hDC, obkc); 2137 return CallWindowProcA (infoPtr->prevComboWndProc, 2138 2137 return CallWindowProcA (infoPtr->prevComboWndProc, 2138 hwnd, uMsg, wParam, lParam); 2139 2139 2140 2140 case WM_SETCURSOR: 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 return CallWindowProcA (infoPtr->prevComboWndProc, 2153 2141 /* 2142 * WM_NOTIFY to comboex parent (rebar) 2143 * with NM_SETCURSOR with extra words of 0,0,0,0,0x02010001 2144 * CallWindowProc (previous) 2145 */ 2146 nmmse.dwItemSpec = 0; 2147 nmmse.dwItemData = 0; 2148 nmmse.pt.x = 0; 2149 nmmse.pt.y = 0; 2150 nmmse.dwHitInfo = lParam; 2151 COMBOEX_Notify (infoPtr, NM_SETCURSOR, (NMHDR *)&nmmse); 2152 return CallWindowProcA (infoPtr->prevComboWndProc, 2153 hwnd, uMsg, wParam, lParam); 2154 2154 2155 2155 case WM_COMMAND: 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 (WPARAM)focusedhwnd, 0); 2197 2198 2199 2200 /* 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 /* 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2156 switch (HIWORD(wParam)) { 2157 2158 case EN_UPDATE: 2159 /* traces show that COMBOEX does not issue CBN_EDITUPDATE 2160 * on the EN_UPDATE 2161 */ 2162 return 0; 2163 2164 case EN_KILLFOCUS: 2165 /* 2166 * Native does: 2167 * 2168 * GetFocus() retns AA 2169 * GetWindowTextA(Edit) 2170 * CB_GETCURSEL(Combo) (got -1) 2171 * WM_NOTIFY(CBEN_ENDEDITA) with CBENF_KILLFOCUS 2172 * CB_GETCURSEL(Combo) (got -1) 2173 * InvalidateRect(Combo, 0, 0) 2174 * WM_KILLFOCUS(Combo, AA) 2175 * return 0; 2176 */ 2177 focusedhwnd = GetFocus(); 2178 if (infoPtr->flags & WCBE_ACTEDIT) { 2179 GetWindowTextW (infoPtr->hwndEdit, edit_text, 260); 2180 cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG); 2181 cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo, 2182 CB_GETCURSEL, 0, 0); 2183 cbeend.iWhy = CBENF_KILLFOCUS; 2184 2185 infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG); 2186 if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) { 2187 /* abort the change */ 2188 TRACE("Notify requested abort of change\n"); 2189 return 0; 2190 } 2191 } 2192 /* possible CB_GETCURSEL */ 2193 InvalidateRect (infoPtr->hwndCombo, 0, 0); 2194 if (focusedhwnd) 2195 SendMessageW (infoPtr->hwndCombo, WM_KILLFOCUS, 2196 (WPARAM)focusedhwnd, 0); 2197 return 0; 2198 2199 case EN_SETFOCUS: { 2200 /* 2201 * For EN_SETFOCUS this issues the same calls and messages 2202 * as the native seems to do. 2203 * 2204 * for some cases however native does the following: 2205 * (noticed after SetFocus during LBUTTONDOWN on 2206 * on dropdown arrow) 2207 * WM_GETTEXTLENGTH (Edit); 2208 * WM_GETTEXT (Edit, len+1, str); 2209 * EM_SETSEL (Edit, 0, 0); 2210 * WM_GETTEXTLENGTH (Edit); 2211 * WM_GETTEXT (Edit, len+1, str); 2212 * EM_SETSEL (Edit, 0, len); 2213 * WM_NOTIFY (parent, CBEN_BEGINEDIT) 2214 */ 2215 NMHDR hdr; 2216 2217 SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0); 2218 SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1); 2219 COMBOEX_Notify (infoPtr, CBEN_BEGINEDIT, &hdr); 2220 infoPtr->flags |= WCBE_ACTEDIT; 2221 infoPtr->flags &= ~WCBE_EDITCHG; /* no change yet */ 2222 return 0; 2223 } 2224 2225 case EN_CHANGE: { 2226 /* 2227 * For EN_CHANGE this issues the same calls and messages 2228 * as the native seems to do. 2229 */ 2230 WCHAR edit_text[260]; 2231 WCHAR *lastwrk; 2232 INT selected, cnt; 2233 CBE_ITEMDATA *item; 2234 2235 selected = SendMessageW (infoPtr->hwndCombo, 2236 CB_GETCURSEL, 0, 0); 2237 2238 /* lstrlenA( lastworkingURL ) */ 2239 2240 GetWindowTextW (infoPtr->hwndEdit, edit_text, 260); 2241 if (selected == -1) { 2242 lastwrk = infoPtr->edit->pszText; 2243 cnt = lstrlenW (lastwrk); 2244 if (cnt >= 259) cnt = 259; 2245 } 2246 else { 2247 item = COMBOEX_FindItem (infoPtr, selected); 2248 cnt = lstrlenW (item->pszText); 2249 lastwrk = item->pszText; 2250 if (cnt >= 259) cnt = 259; 2251 } 2252 2253 TRACE("handling EN_CHANGE, selected = %d, selected_text=%s\n", 2254 selected, debugstr_w(lastwrk)); 2255 TRACE("handling EN_CHANGE, edittext=%s\n", 2256 debugstr_w(edit_text)); 2257 2258 /* lstrcmpiW is between lastworkingURL and GetWindowText */ 2259 2260 if (lstrcmpiW (lastwrk, edit_text)) { 2261 /* strings not equal -- indicate edit has changed */ 2262 infoPtr->flags |= WCBE_EDITCHG; 2263 } 2264 SendMessageW ( GetParent(infoPtr->hwndSelf), WM_COMMAND, 2265 MAKEWPARAM(GetDlgCtrlID (infoPtr->hwndSelf), 2266 CBN_EDITCHANGE), 2267 infoPtr->hwndSelf); 2268 return 0; 2269 } 2270 2271 case LBN_SELCHANGE: 2272 /* 2273 * Therefore from traces there is no additional code here 2274 */ 2275 2276 /* 2277 * Using native COMCTL32 gets the following: 2278 * 1 == SHDOCVW.DLL issues call/message 2279 * 2 == COMCTL32.DLL issues call/message 2280 * 3 == WINE issues call/message 2281 * 2282 * 2283 * for LBN_SELCHANGE: 2284 * 1 CB_GETCURSEL(ComboEx) 2285 * 1 CB_GETDROPPEDSTATE(ComboEx) 2286 * 1 CallWindowProc( *2* for WM_COMMAND(LBN_SELCHANGE) 2287 * 2 CallWindowProc( *3* for WM_COMMAND(LBN_SELCHANGE) 2288 ** call CBRollUp( xxx, TRUE for LBN_SELCHANGE, TRUE) 2289 * 3 WM_COMMAND(ComboEx, CBN_SELENDOK) 2290 * WM_USER+49(ComboLB, 1,0) <=============!!!!!!!!!!! 2291 * 3 ShowWindow(ComboLB, SW_HIDE) 2292 * 3 RedrawWindow(Combo, RDW_UPDATENOW) 2293 * 3 WM_COMMAND(ComboEX, CBN_CLOSEUP) 2294 ** end of CBRollUp 2295 * 3 WM_COMMAND(ComboEx, CBN_SELCHANGE) (echo to parent) 2296 * ? LB_GETCURSEL <==| 2297 * ? LB_GETTEXTLEN | 2298 * ? LB_GETTEXT | Needs to be added to 2299 * ? WM_CTLCOLOREDIT(ComboEx) | Combo processing 2300 * ? LB_GETITEMDATA | 2301 * ? WM_DRAWITEM(ComboEx) <==| 2302 */ 2303 default: 2304 break; 2305 }/* fall through */ 2306 2306 default: 2307 return CallWindowProcA (infoPtr->prevComboWndProc, 2308 2307 return CallWindowProcA (infoPtr->prevComboWndProc, 2308 hwnd, uMsg, wParam, lParam); 2309 2309 } 2310 2310 return 0; … … 2320 2320 2321 2321 if (!COMBOEX_GetInfoPtr (hwnd)) { 2322 2323 2324 2325 2322 if (uMsg == WM_CREATE) 2323 return COMBOEX_Create (hwnd, wParam, lParam); 2324 if (uMsg == WM_NCCREATE) 2325 COMBOEX_NCCreate (hwnd, wParam, lParam); 2326 2326 return DefWindowProcA (hwnd, uMsg, wParam, lParam); 2327 2327 } … … 2330 2330 { 2331 2331 case CBEM_DELETEITEM: /* maps to CB_DELETESTRING */ 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 case CBEM_SETEXSTYLE:/* FIXME: obsoleted, should be the same as: */2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2332 return COMBOEX_DeleteItem (hwnd, wParam, lParam); 2333 2334 case CBEM_GETCOMBOCONTROL: 2335 return COMBOEX_GetComboControl (hwnd, wParam, lParam); 2336 2337 case CBEM_GETEDITCONTROL: 2338 return COMBOEX_GetEditControl (hwnd, wParam, lParam); 2339 2340 case CBEM_GETEXTENDEDSTYLE: 2341 return COMBOEX_GetExtendedStyle (hwnd, wParam, lParam); 2342 2343 case CBEM_GETIMAGELIST: 2344 return COMBOEX_GetImageList (hwnd, wParam, lParam); 2345 2346 case CBEM_GETITEMA: 2347 return COMBOEX_GetItemA (hwnd, wParam, lParam); 2348 2349 case CBEM_GETITEMW: 2350 return COMBOEX_GetItemW (hwnd, wParam, lParam); 2351 2352 case CBEM_GETUNICODEFORMAT: 2353 return COMBOEX_GetUnicodeFormat (hwnd, wParam, lParam); 2354 2355 case CBEM_HASEDITCHANGED: 2356 return COMBOEX_HasEditChanged (hwnd, wParam, lParam); 2357 2358 case CBEM_INSERTITEMA: 2359 return COMBOEX_InsertItemA (hwnd, wParam, lParam); 2360 2361 case CBEM_INSERTITEMW: 2362 return COMBOEX_InsertItemW (hwnd, wParam, lParam); 2363 2364 case CBEM_SETEXSTYLE: /* FIXME: obsoleted, should be the same as: */ 2365 case CBEM_SETEXTENDEDSTYLE: 2366 return COMBOEX_SetExtendedStyle (hwnd, wParam, lParam); 2367 2368 case CBEM_SETIMAGELIST: 2369 return COMBOEX_SetImageList (hwnd, wParam, lParam); 2370 2371 case CBEM_SETITEMA: 2372 return COMBOEX_SetItemA (hwnd, wParam, lParam); 2373 2374 case CBEM_SETITEMW: 2375 return COMBOEX_SetItemW (hwnd, wParam, lParam); 2376 2377 case CBEM_SETUNICODEFORMAT: 2378 return COMBOEX_SetUnicodeFormat (hwnd, wParam, lParam); 2379 2379 2380 2380 2381 2381 /* Combo messages we are not sure if we need to process or just forward */ 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2382 case CB_GETDROPPEDCONTROLRECT: 2383 case CB_GETITEMHEIGHT: 2384 case CB_GETLBTEXT: 2385 case CB_GETLBTEXTLEN: 2386 case CB_GETEXTENDEDUI: 2387 case CB_LIMITTEXT: 2388 case CB_RESETCONTENT: 2389 case CB_SELECTSTRING: 2390 case WM_SETTEXT: 2391 case WM_GETTEXT: 2392 FIXME("(0x%x 0x%x 0x%lx): possibly missing function\n", 2393 uMsg, wParam, lParam); 2394 return COMBOEX_Forward (hwnd, uMsg, wParam, lParam); 2395 2395 2396 2396 /* Combo messages OK to just forward to the regular COMBO */ 2397 case CB_GETCOUNT: 2398 2399 2397 case CB_GETCOUNT: 2398 case CB_GETCURSEL: 2399 case CB_GETDROPPEDSTATE: 2400 2400 case CB_SETDROPPEDWIDTH: 2401 2401 case CB_SETEXTENDEDUI: 2402 2402 case CB_SHOWDROPDOWN: 2403 2403 return COMBOEX_Forward (hwnd, uMsg, wParam, lParam); 2404 2404 2405 2405 /* Combo messages we need to process specially */ 2406 2406 case CB_FINDSTRINGEXACT: 2407 return COMBOEX_FindStringExact (COMBOEX_GetInfoPtr (hwnd), 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2407 return COMBOEX_FindStringExact (COMBOEX_GetInfoPtr (hwnd), 2408 wParam, lParam); 2409 2410 case CB_GETITEMDATA: 2411 return COMBOEX_GetItemData (hwnd, wParam, lParam); 2412 2413 case CB_SETCURSEL: 2414 return COMBOEX_SetCursel (hwnd, wParam, lParam); 2415 2416 case CB_SETITEMDATA: 2417 return COMBOEX_SetItemData (hwnd, wParam, lParam); 2418 2419 case CB_SETITEMHEIGHT: 2420 return COMBOEX_SetItemHeight (hwnd, wParam, lParam); 2421 2421 2422 2422 2423 2423 2424 2424 /* Window messages passed to parent */ 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2425 case WM_COMMAND: 2426 return COMBOEX_Command (hwnd, wParam, lParam); 2427 2428 case WM_NOTIFY: 2429 if (infoPtr->NtfUnicode) 2430 return SendMessageW (GetParent (hwnd), 2431 uMsg, wParam, lParam); 2432 else 2433 return SendMessageA (GetParent (hwnd), 2434 uMsg, wParam, lParam); 2435 2435 2436 2436 2437 2437 /* Window messages we need to process */ 2438 2438 case WM_DELETEITEM: 2439 2439 return COMBOEX_WM_DeleteItem (hwnd, wParam, lParam); 2440 2440 2441 2441 case WM_DRAWITEM: 2442 2442 return COMBOEX_DrawItem (hwnd, wParam, lParam); 2443 2443 2444 2445 2444 case WM_DESTROY: 2445 return COMBOEX_Destroy (hwnd, wParam, lParam); 2446 2446 2447 2447 case WM_MEASUREITEM: … … 2449 2449 2450 2450 case WM_NOTIFYFORMAT: 2451 2452 2453 2454 2451 return COMBOEX_NotifyFormat (hwnd, wParam, lParam); 2452 2453 case WM_SIZE: 2454 return COMBOEX_Size (hwnd, wParam, lParam); 2455 2455 2456 2456 case WM_WINDOWPOSCHANGING: 2457 2458 2459 2460 2461 2462 2457 return COMBOEX_WindowPosChanging (hwnd, wParam, lParam); 2458 2459 default: 2460 if (uMsg >= WM_USER) 2461 ERR("unknown msg %04x wp=%08x lp=%08lx\n", 2462 uMsg, wParam, lParam); 2463 2463 #ifdef __WIN32OS2__ 2464 2464 return defComCtl32ProcA (hwnd, uMsg, wParam, lParam); 2465 2465 #else 2466 2466 return DefWindowProcA (hwnd, uMsg, wParam, lParam); 2467 2467 #endif 2468 2468 } … … 2484 2484 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 2485 2485 wndClass.lpszClassName = WC_COMBOBOXEXA; 2486 2486 2487 2487 RegisterClassA (&wndClass); 2488 2488 -
trunk/src/comctl32/comctl32.c
r6705 r6709 1 /* 1 /* 2 2 * Common controls functions 3 3 * … … 99 99 100 100 switch (fdwReason) { 101 101 case DLL_PROCESS_ATTACH: 102 102 COMCTL32_hModule = (HMODULE)hinstDLL; 103 103 … … 130 130 break; 131 131 132 132 case DLL_PROCESS_DETACH: 133 133 /* unregister all common control classes */ 134 134 ANIMATE_Unregister (); … … 204 204 VOID WINAPI 205 205 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu, 206 206 HINSTANCE hInst, HWND hwndStatus, LPUINT lpwIDs) 207 207 { 208 208 UINT uMenuID = 0; 209 209 210 210 if (!IsWindow (hwndStatus)) 211 211 return; 212 212 213 213 switch (uMsg) { 214 215 216 214 case WM_MENUSELECT: 215 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n", 216 wParam, lParam); 217 217 218 218 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) { 219 219 /* menu was closed */ 220 220 TRACE("menu was closed!\n"); 221 221 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0); 222 222 } 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 223 else { 224 /* menu item was selected */ 225 if (HIWORD(wParam) & MF_POPUP) 226 uMenuID = (UINT)*(lpwIDs+1); 227 else 228 uMenuID = (UINT)LOWORD(wParam); 229 TRACE("uMenuID = %u\n", uMenuID); 230 231 if (uMenuID) { 232 CHAR szText[256]; 233 234 if (!LoadStringA (hInst, uMenuID, szText, 256)) 235 szText[0] = '\0'; 236 237 SendMessageA (hwndStatus, SB_SETTEXTA, 238 255 | SBT_NOBORDERS, (LPARAM)szText); 239 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0); 240 } 241 } 242 break; 243 243 244 244 case WM_COMMAND : 245 246 247 248 245 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n", 246 wParam, lParam); 247 /* WM_COMMAND is not invalid since it is documented 248 * in the windows api reference. So don't output 249 249 * any FIXME for WM_COMMAND 250 250 */ 251 252 253 254 255 256 257 } 258 } 259 260 261 /*********************************************************************** 262 * ShowHideMenuCtl [COMCTL32.3] 251 WARN("We don't care about the WM_COMMAND\n"); 252 break; 253 254 default: 255 FIXME("Invalid Message 0x%x!\n", uMsg); 256 break; 257 } 258 } 259 260 261 /*********************************************************************** 262 * ShowHideMenuCtl [COMCTL32.3] 263 263 * 264 264 * Shows or hides controls and updates the corresponding menu item. … … 297 297 298 298 if (lpInfo == NULL) 299 299 return FALSE; 300 300 301 301 if (!(lpInfo[0]) || !(lpInfo[1])) 302 302 return FALSE; 303 303 304 304 /* search for control */ 305 305 lpMenuId = &lpInfo[2]; 306 306 while (*lpMenuId != uFlags) 307 307 lpMenuId += 2; 308 308 309 309 if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) { 310 311 312 313 314 315 316 310 /* uncheck menu item */ 311 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED); 312 313 /* hide control */ 314 lpMenuId++; 315 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0, 316 SWP_HIDEWINDOW); 317 317 } 318 318 else { 319 320 321 322 323 324 325 319 /* check menu item */ 320 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED); 321 322 /* show control */ 323 lpMenuId++; 324 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0, 325 SWP_SHOWWINDOW); 326 326 } 327 327 … … 357 357 358 358 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n", 359 359 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo); 360 360 361 361 GetClientRect (hwnd, lpRect); … … 363 363 364 364 do { 365 366 367 368 369 370 371 372 373 374 375 376 365 lpRun += 2; 366 if (*lpRun == 0) 367 return; 368 lpRun++; 369 hwndCtrl = GetDlgItem (hwnd, *lpRun); 370 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) { 371 TRACE("control id 0x%x\n", *lpRun); 372 GetWindowRect (hwndCtrl, &rcCtrl); 373 MapWindowPoints ((HWND)0, hwnd, (LPPOINT)&rcCtrl, 2); 374 SubtractRect (lpRect, lpRect, &rcCtrl); 375 } 376 lpRun++; 377 377 } while (*lpRun); 378 378 } … … 416 416 r.left += 3; 417 417 DrawTextA (hdc, text, lstrlenA(text), 418 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE); 418 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE); 419 419 if (oldbkmode != TRANSPARENT) 420 420 SetBkMode(hdc, oldbkmode); 421 421 } 422 422 } … … 466 466 CreateStatusWindowA (INT style, LPCSTR text, HWND parent, UINT wid) 467 467 { 468 return CreateWindowA(STATUSCLASSNAMEA, text, style, 469 470 CW_USEDEFAULT, CW_USEDEFAULT, 471 468 return CreateWindowA(STATUSCLASSNAMEA, text, style, 469 CW_USEDEFAULT, CW_USEDEFAULT, 470 CW_USEDEFAULT, CW_USEDEFAULT, 471 parent, wid, 0, 0); 472 472 } 473 473 … … 491 491 { 492 492 return CreateWindowW(STATUSCLASSNAMEW, text, style, 493 494 495 493 CW_USEDEFAULT, CW_USEDEFAULT, 494 CW_USEDEFAULT, CW_USEDEFAULT, 495 parent, wid, 0, 0); 496 496 } 497 497 … … 521 521 HWND WINAPI 522 522 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy, 523 524 523 HWND parent, INT id, HINSTANCE inst, 524 HWND buddy, INT maxVal, INT minVal, INT curVal) 525 525 { 526 526 HWND hUD = 527 528 527 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy, 528 parent, id, inst, 0); 529 529 if (hUD) { 530 531 532 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0)); 530 SendMessageA (hUD, UDM_SETBUDDY, buddy, 0); 531 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal)); 532 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0)); 533 533 } 534 534 … … 584 584 585 585 if (!lpInitCtrls) 586 586 return FALSE; 587 587 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX)) 588 588 return FALSE; 589 589 590 590 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC); 591 591 592 592 for (cCount = 0; cCount < 32; cCount++) { 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 593 dwMask = 1 << cCount; 594 if (!(lpInitCtrls->dwICC & dwMask)) 595 continue; 596 597 switch (lpInitCtrls->dwICC & dwMask) { 598 /* dummy initialization */ 599 case ICC_ANIMATE_CLASS: 600 case ICC_BAR_CLASSES: 601 case ICC_LISTVIEW_CLASSES: 602 case ICC_TREEVIEW_CLASSES: 603 case ICC_TAB_CLASSES: 604 case ICC_UPDOWN_CLASS: 605 case ICC_PROGRESS_CLASS: 606 case ICC_HOTKEY_CLASS: 607 break; 608 609 /* advanced classes - not included in Win95 */ 610 case ICC_DATE_CLASSES: 611 MONTHCAL_Register (); 612 DATETIME_Register (); 613 break; 614 615 case ICC_USEREX_CLASSES: 616 COMBOEX_Register (); 617 break; 618 619 case ICC_COOL_CLASSES: 620 REBAR_Register (); 621 break; 622 623 case ICC_INTERNET_CLASSES: 624 IPADDRESS_Register (); 625 break; 626 627 case ICC_PAGESCROLLER_CLASS: 628 PAGER_Register (); 629 break; 630 631 case ICC_NATIVEFNTCTL_CLASS: 632 NATIVEFONT_Register (); 633 break; 634 635 default: 636 FIXME("Unknown class! dwICC=0x%lX\n", dwMask); 637 break; 638 } 639 639 } 640 640 … … 681 681 hwndTB = 682 682 CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style|WS_CHILD, 0, 0, 0, 0, 683 683 hwnd, (HMENU)wID, 0, NULL); 684 684 if(hwndTB) { 685 685 TBADDBITMAP tbab; 686 686 687 687 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE, 688 688 (WPARAM)uStructSize, 0); 689 689 690 690 /* set bitmap and button size */ … … 705 705 706 706 707 708 709 710 711 712 713 714 715 716 717 718 719 707 /* add bitmaps */ 708 if (nBitmaps > 0) 709 { 710 tbab.hInst = hBMInst; 711 tbab.nID = wBMID; 712 713 SendMessageA (hwndTB, TB_ADDBITMAP, 714 (WPARAM)nBitmaps, (LPARAM)&tbab); 715 } 716 /* add buttons */ 717 if(iNumButtons > 0) 718 SendMessageA (hwndTB, TB_ADDBUTTONSA, 719 (WPARAM)iNumButtons, (LPARAM)lpButtons); 720 720 } 721 721 … … 741 741 HBITMAP WINAPI 742 742 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags, 743 743 LPCOLORMAP lpColorMap, INT iNumMaps) 744 744 { 745 745 HGLOBAL hglb; … … 754 754 COLORREF cRef; 755 755 COLORMAP internalColorMap[4] = 756 756 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}}; 757 757 758 758 /* initialize pointer to colortable and default color table */ 759 759 if (lpColorMap) { 760 761 760 iMaps = iNumMaps; 761 sysColorMap = lpColorMap; 762 762 } 763 763 else { 764 765 766 767 768 769 764 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT); 765 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW); 766 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE); 767 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT); 768 iMaps = 4; 769 sysColorMap = (LPCOLORMAP)internalColorMap; 770 770 } 771 771 772 772 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, RT_BITMAPA); 773 773 if (hRsrc == 0) 774 774 return 0; 775 775 hglb = LoadResource (hInstance, hRsrc); 776 776 if (hglb == 0) 777 777 return 0; 778 778 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb); 779 779 if (lpBitmap == NULL) 780 780 return 0; 781 781 782 782 nColorTableSize = (1 << lpBitmap->biBitCount); … … 784 784 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize); 785 785 if (lpBitmapInfo == NULL) 786 786 return 0; 787 787 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize); 788 788 … … 790 790 791 791 for (iColor = 0; iColor < nColorTableSize; iColor++) { 792 792 for (i = 0; i < iMaps; i++) { 793 793 cRef = RGB(pColorTable[iColor].rgbRed, 794 794 pColorTable[iColor].rgbGreen, 795 795 pColorTable[iColor].rgbBlue); 796 796 if ( cRef == sysColorMap[i].from) { 797 797 #if 0 798 799 800 801 802 798 if (wFlags & CBS_MASKED) { 799 if (sysColorMap[i].to != COLOR_BTNTEXT) 800 pColorTable[iColor] = RGB(255, 255, 255); 801 } 802 else 803 803 #endif 804 804 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to); 805 805 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to); 806 806 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to); 807 808 809 807 break; 808 } 809 } 810 810 } 811 811 nWidth = (INT)lpBitmapInfo->biWidth; … … 814 814 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight); 815 815 if (hbm) { 816 817 818 819 820 821 822 823 824 816 HDC hdcDst = CreateCompatibleDC (hdcScreen); 817 HBITMAP hbmOld = SelectObject (hdcDst, hbm); 818 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1); 819 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD); 820 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight, 821 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS, 822 SRCCOPY); 823 SelectObject (hdcDst, hbmOld); 824 DeleteDC (hdcDst); 825 825 } 826 826 ReleaseDC ((HWND)0, hdcScreen); … … 855 855 HWND WINAPI 856 856 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps, 857 858 857 HINSTANCE hBMInst, UINT wBMID, 858 LPCOLDTBBUTTON lpButtons,INT iNumButtons) 859 859 { 860 860 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps, 861 862 861 hBMInst, wBMID, (LPCTBBUTTON)lpButtons, 862 iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON)); 863 863 } 864 864 … … 885 885 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) { 886 886 WARN("wrong DLLVERSIONINFO size from app"); 887 887 return E_INVALIDARG; 888 888 } 889 889 … … 894 894 895 895 TRACE("%lu.%lu.%lu.%lu\n", 896 897 896 pdvi->dwMajorVersion, pdvi->dwMinorVersion, 897 pdvi->dwBuildNumber, pdvi->dwPlatformID); 898 898 899 899 return S_OK; … … 901 901 902 902 /*********************************************************************** 903 * 903 * DllInstall (COMCTL32.@) 904 904 */ 905 905 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline) 906 906 { 907 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE", 908 907 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE", 908 debugstr_w(cmdline)); 909 909 910 910 return S_OK; … … 916 916 POINT pos; /* center of hover rectangle */ 917 917 INT iHoverTime; /* elapsed time the cursor has been inside of the hover rect */ 918 } _TRACKINGLIST; 918 } _TRACKINGLIST; 919 919 920 920 static _TRACKINGLIST TrackingList[10]; … … 955 955 if(TrackingList[i].tme.dwFlags & TME_HOVER) { 956 956 /* add the timer interval to the hovering time */ 957 TrackingList[i].iHoverTime+=iTimerInterval; 958 957 TrackingList[i].iHoverTime+=iTimerInterval; 958 959 959 /* has the cursor moved outside the rectangle centered around pos? */ 960 960 if((abs(pos.x - TrackingList[i].pos.x) > (hoverwidth / 2.0)) … … 985 985 } 986 986 } 987 987 988 988 /* stop the timer if the tracking list is empty */ 989 989 if(iTrackMax == 0) { … … 1036 1036 1037 1037 flags = ptme->dwFlags; 1038 1038 1039 1039 /* if HOVER_DEFAULT was specified replace this with the systems current value */ 1040 1040 if(ptme->dwHoverTime == HOVER_DEFAULT) … … 1042 1042 1043 1043 GetCursorPos(&pos); 1044 hwnd = WindowFromPoint(pos); 1044 hwnd = WindowFromPoint(pos); 1045 1045 1046 1046 if ( flags & TME_CANCEL ) { … … 1048 1048 cancel = 1; 1049 1049 } 1050 1050 1051 1051 if ( flags & TME_HOVER ) { 1052 1052 flags &= ~ TME_HOVER; 1053 1053 hover = 1; 1054 1054 } 1055 1055 1056 1056 if ( flags & TME_LEAVE ) { 1057 1057 flags &= ~ TME_LEAVE; … … 1075 1075 else 1076 1076 ptme->dwFlags = 0; 1077 1077 1078 1078 return TRUE; /* return here, TME_QUERY is retrieving information */ 1079 1079 } … … 1098 1098 { 1099 1099 TrackingList[i] = TrackingList[--iTrackMax]; 1100 1100 1101 1101 if(iTrackMax == 0) { 1102 1102 KillTimer(0, timer); … … 1119 1119 TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime; 1120 1120 } 1121 1121 1122 1122 if(leave) 1123 1123 TrackingList[i].tme.dwFlags |= TME_LEAVE; 1124 1124 1125 1125 /* reset iHoverTime as per winapi specs */ 1126 TrackingList[i].iHoverTime = 0; 1127 1126 TrackingList[i].iHoverTime = 0; 1127 1128 1128 return TRUE; 1129 1129 } 1130 } 1130 } 1131 1131 1132 1132 /* if the tracking list is full return FALSE */ … … 1198 1198 1199 1199 hwndToolTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0, 1200 1201 1202 1200 CW_USEDEFAULT, CW_USEDEFAULT, 1201 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, 1202 0, 0, 0); 1203 1203 1204 1204 /* Send NM_TOOLTIPSCREATED notification */ 1205 1205 if (hwndToolTip) 1206 1206 { 1207 1207 NMTOOLTIPSCREATED nmttc; 1208 1208 /* true owner can be different if hwndOwner is a child window */ 1209 1209 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER); 1210 1210 nmttc.hdr.hwndFrom = hwndTrueOwner; 1211 1211 nmttc.hdr.idFrom = GetWindowLongA(hwndTrueOwner, GWL_ID); 1212 1213 1212 nmttc.hdr.code = NM_TOOLTIPSCREATED; 1213 nmttc.hwndToolTips = hwndToolTip; 1214 1214 1215 1215 SendMessageA(GetParent(hwndTrueOwner), WM_NOTIFY, 1216 1216 (WPARAM)GetWindowLongA(hwndTrueOwner, GWL_ID), 1217 1217 (LPARAM)&nmttc); 1218 1218 } 1219 1219 -
trunk/src/comctl32/comctl32undoc.c
r6705 r6709 98 98 99 99 FIXME ("phDpa=%p loadProc=%p pStream=%p lParam=%lx\n", 100 100 phDpa, loadProc, pStream, lParam); 101 101 102 102 if (!phDpa || !loadProc || !pStream) 103 103 return E_INVALIDARG; 104 104 105 105 *phDpa = (HDPA)NULL; … … 110 110 errCode = IStream_Seek (pStream, position, STREAM_SEEK_CUR, &newPosition); 111 111 if (errCode != S_OK) 112 112 return errCode; 113 113 114 114 errCode = IStream_Read (pStream, &streamData, sizeof(STREAMDATA), &ulRead); 115 115 if (errCode != S_OK) 116 116 return errCode; 117 117 118 118 FIXME ("dwSize=%lu dwData2=%lu dwItems=%lu\n", 119 119 streamData.dwSize, streamData.dwData2, streamData.dwItems); 120 120 121 121 if (lParam < sizeof(STREAMDATA) || 122 123 124 122 streamData.dwSize < sizeof(STREAMDATA) || 123 streamData.dwData2 < 1) { 124 errCode = E_FAIL; 125 125 } 126 126 … … 128 128 hDpa = DPA_Create (streamData.dwItems); 129 129 if (!hDpa) 130 130 return E_OUTOFMEMORY; 131 131 132 132 if (!DPA_Grow (hDpa, streamData.dwItems)) 133 133 return E_OUTOFMEMORY; 134 134 135 135 /* load data from the stream into the dpa */ … … 137 137 for (loadData.nCount = 0; loadData.nCount < streamData.dwItems; loadData.nCount++) { 138 138 errCode = (loadProc)(&loadData, pStream, lParam); 139 140 141 142 143 144 145 139 if (errCode != S_OK) { 140 errCode = S_FALSE; 141 break; 142 } 143 144 *ptr = loadData.ptr; 145 ptr++; 146 146 } 147 147 … … 177 177 178 178 FIXME ("hDpa=%p loadProc=%p pStream=%p lParam=%lx\n", 179 179 hDpa, loadProc, pStream, lParam); 180 180 181 181 return E_FAIL; … … 200 200 BOOL WINAPI 201 201 DPA_Merge (const HDPA hdpa1, const HDPA hdpa2, DWORD dwFlags, 202 202 PFNDPACOMPARE pfnCompare, PFNDPAMERGE pfnMerge, LPARAM lParam) 203 203 { 204 204 INT nCount; … … 208 208 209 209 TRACE("%p %p %08lx %p %p %08lx)\n", 210 210 hdpa1, hdpa2, dwFlags, pfnCompare, pfnMerge, lParam); 211 211 212 212 if (IsBadWritePtr (hdpa1, sizeof(DPA))) 213 213 return FALSE; 214 214 215 215 if (IsBadWritePtr (hdpa2, sizeof(DPA))) 216 216 return FALSE; 217 217 218 218 if (IsBadCodePtr ((FARPROC)pfnCompare)) 219 219 return FALSE; 220 220 221 221 if (IsBadCodePtr ((FARPROC)pfnMerge)) 222 222 return FALSE; 223 223 224 224 if (dwFlags & DPAM_SORT) { 225 226 227 228 229 230 231 225 TRACE("sorting dpa's!\n"); 226 if (hdpa1->nItemCount > 0) 227 DPA_Sort (hdpa1, pfnCompare, lParam); 228 TRACE ("dpa 1 sorted!\n"); 229 if (hdpa2->nItemCount > 0) 230 DPA_Sort (hdpa2, pfnCompare, lParam); 231 TRACE ("dpa 2 sorted!\n"); 232 232 } 233 233 234 234 if (hdpa2->nItemCount < 1) 235 235 return TRUE; 236 236 237 237 TRACE("hdpa1->nItemCount=%d hdpa2->nItemCount=%d\n", 238 238 hdpa1->nItemCount, hdpa2->nItemCount); 239 239 240 240 … … 250 250 { 251 251 if (nIndex < 0) break; 252 253 TRACE("compare result=%d, dpa1.cnt=%d, dpa2.cnt=%d\n", 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 252 nResult = (pfnCompare)(*pWork1, *pWork2, lParam); 253 TRACE("compare result=%d, dpa1.cnt=%d, dpa2.cnt=%d\n", 254 nResult, nIndex, nCount); 255 256 if (nResult == 0) 257 { 258 PVOID ptr; 259 260 ptr = (pfnMerge)(1, *pWork1, *pWork2, lParam); 261 if (!ptr) 262 return FALSE; 263 264 nCount--; 265 pWork2--; 266 *pWork1 = ptr; 267 nIndex--; 268 pWork1--; 269 } 270 else if (nResult < 0) 271 { 272 if (!dwFlags & 8) 273 { 274 PVOID ptr; 275 276 ptr = DPA_DeletePtr (hdpa1, hdpa1->nItemCount - 1); 277 278 (pfnMerge)(2, ptr, NULL, lParam); 279 } 280 nIndex--; 281 pWork1--; 282 } 283 else 284 { 285 if (!dwFlags & 4) 286 { 287 PVOID ptr; 288 289 ptr = (pfnMerge)(3, *pWork2, NULL, lParam); 290 if (!ptr) 291 return FALSE; 292 DPA_InsertPtr (hdpa1, nIndex, ptr); 293 } 294 nCount--; 295 pWork2--; 296 } 297 297 298 298 } … … 358 358 359 359 if (lpSrc) 360 360 lpDest = HeapReAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, lpSrc, dwSize); 361 361 else 362 362 lpDest = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize); 363 363 364 364 TRACE("-- ret=%p\n", lpDest); … … 458 458 HANDLE WINAPI 459 459 CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2, 460 460 DWORD dwParam3, DWORD dwParam4); 461 461 462 462 … … 490 490 #if 0 491 491 if (!(hmru->dwParam1 & 1001)) { 492 493 494 492 RegSetValueExA (hmru->hKeyMRU, "MRUList", 0, REG_SZ, 493 hmru->lpszMRUString, 494 strlen (hmru->lpszMRUString)); 495 495 } 496 496 … … 506 506 /************************************************************************** 507 507 * AddMRUData [COMCTL32.167] 508 * 508 * 509 509 * Add item to MRU binary list. If item already exists in list then it is 510 510 * simply moved up to the top of the list and not added again. If list is … … 530 530 /************************************************************************** 531 531 * AddMRUStringA [COMCTL32.153] 532 * 532 * 533 533 * Add item to MRU string list. If item already exists in list them it is 534 534 * simply moved up to the top of the list and not added again. If list is … … 572 572 /************************************************************************** 573 573 * FindMRUData [COMCTL32.169] 574 * 574 * 575 575 * Searches binary list for item that matches lpData of length cbData. 576 576 * Returns position in list order 0 -> MRU and if lpRegNum != NULL then value … … 590 590 { 591 591 FIXME("(%08x, %p, %ld, %p) empty stub!\n", 592 592 hList, lpData, cbData, lpRegNum); 593 593 594 594 return 0; … … 597 597 /************************************************************************** 598 598 * FindMRUStringA [COMCTL32.155] 599 * 599 * 600 600 * Searches string list for item that matches lpszString. 601 601 * Returns position in list order 0 -> MRU and if lpRegNum != NULL then value … … 614 614 { 615 615 FIXME("(%08x, %s, %p) empty stub!\n", hList, debugstr_a(lpszString), 616 616 lpRegNum); 617 617 618 618 return 0; … … 640 640 641 641 if (lpcml == NULL) 642 642 return 0; 643 643 644 644 if (lpcml->cbSize < sizeof(CREATEMRULIST)) 645 645 return 0; 646 646 647 647 FIXME("(%lu %lu %lx %lx \"%s\" %p)\n", 648 649 648 lpcml->cbSize, lpcml->nMaxItems, lpcml->dwFlags, 649 (DWORD)lpcml->hKey, lpcml->lpszSubKey, lpcml->lpfnCompare); 650 650 651 651 /* dummy pointer creation */ … … 659 659 /************************************************************************** 660 660 * EnumMRUListA [COMCTL32.154] 661 * 661 * 662 662 * Enumerate item in a list 663 663 * … … 673 673 * of list returns -1. 674 674 * If lpBuffer == NULL or nItemPos is -ve return value is no. of items in 675 * the list. 675 * the list. 676 676 */ 677 677 INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer, … … 679 679 { 680 680 FIXME("(%08x, %d, %p, %ld): stub\n", hList, nItemPos, lpBuffer, 681 681 nBufferSize); 682 682 return 0; 683 683 } … … 702 702 703 703 if (!lpDest && lpSrc) 704 704 return strlen (lpSrc); 705 705 706 706 if (nMaxLen == 0) 707 707 return 0; 708 708 709 709 if (lpSrc == NULL) { 710 711 710 lpDest[0] = '\0'; 711 return 0; 712 712 } 713 713 714 714 len = strlen (lpSrc); 715 715 if (len >= nMaxLen) 716 716 len = nMaxLen - 1; 717 717 718 718 RtlMoveMemory (lpDest, lpSrc, len); … … 737 737 { 738 738 TRACE("(%p %p)\n", lppDest, lpSrc); 739 739 740 740 if (lpSrc) { 741 742 743 744 745 741 LPSTR ptr = COMCTL32_ReAlloc (*lppDest, strlen (lpSrc) + 1); 742 if (!ptr) 743 return FALSE; 744 strcpy (ptr, lpSrc); 745 *lppDest = ptr; 746 746 } 747 747 else { 748 749 750 751 748 if (*lppDest) { 749 COMCTL32_Free (*lppDest); 750 *lppDest = NULL; 751 } 752 752 } 753 753 … … 775 775 776 776 if (!lpDest && lpSrc) 777 777 return strlenW (lpSrc); 778 778 779 779 if (nMaxLen == 0) 780 780 return 0; 781 781 782 782 if (lpSrc == NULL) { 783 784 783 lpDest[0] = L'\0'; 784 return 0; 785 785 } 786 786 787 787 len = strlenW (lpSrc); 788 788 if (len >= nMaxLen) 789 789 len = nMaxLen - 1; 790 790 791 791 RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR)); … … 810 810 { 811 811 TRACE("(%p %p)\n", lppDest, lpSrc); 812 812 813 813 if (lpSrc) { 814 815 816 817 818 819 814 INT len = strlenW (lpSrc) + 1; 815 LPWSTR ptr = COMCTL32_ReAlloc (*lppDest, len * sizeof(WCHAR)); 816 if (!ptr) 817 return FALSE; 818 strcpyW (ptr, lpSrc); 819 *lppDest = ptr; 820 820 } 821 821 else { 822 823 824 825 822 if (*lppDest) { 823 COMCTL32_Free (*lppDest); 824 *lppDest = NULL; 825 } 826 826 } 827 827 … … 852 852 853 853 if (!lpDest && lpSrc) 854 854 return WideCharToMultiByte(CP_ACP, 0, lpSrc, -1, 0, 0, NULL, NULL); 855 855 856 856 if (nMaxLen == 0) 857 857 return 0; 858 858 859 859 if (lpSrc == NULL) { 860 861 860 lpDest[0] = '\0'; 861 return 0; 862 862 } 863 863 864 864 len = WideCharToMultiByte(CP_ACP, 0, lpSrc, -1, 0, 0, NULL, NULL); 865 865 if (len >= nMaxLen) 866 866 len = nMaxLen - 1; 867 867 868 868 WideCharToMultiByte(CP_ACP, 0, lpSrc, -1, lpDest, len, NULL, NULL); … … 897 897 898 898 if (lpSrc) { 899 900 901 902 903 904 905 899 INT len = MultiByteToWideChar(CP_ACP,0,lpSrc,-1,NULL,0); 900 LPWSTR ptr = COMCTL32_ReAlloc (*lppDest, len*sizeof(WCHAR)); 901 902 if (!ptr) 903 return FALSE; 904 MultiByteToWideChar(CP_ACP,0,lpSrc,-1,ptr,len); 905 *lppDest = ptr; 906 906 } 907 907 else { 908 909 910 911 908 if (*lppDest) { 909 COMCTL32_Free (*lppDest); 910 *lppDest = NULL; 911 } 912 912 } 913 913 … … 944 944 if (hdsa) 945 945 { 946 946 hdsa->nItemCount = 0; 947 947 hdsa->pData = NULL; 948 949 950 948 hdsa->nMaxCount = 0; 949 hdsa->nItemSize = nSize; 950 hdsa->nGrow = max(1, nGrow); 951 951 } 952 952 … … 972 972 973 973 if (!hdsa) 974 974 return FALSE; 975 975 976 976 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData))) 977 977 return FALSE; 978 978 979 979 return COMCTL32_Free (hdsa); … … 982 982 983 983 /************************************************************************** 984 * DSA_GetItem [COMCTL32.322] 984 * DSA_GetItem [COMCTL32.322] 985 985 * 986 986 * PARAMS … … 1000 1000 1001 1001 TRACE("(%p %d %p)\n", hdsa, nIndex, pDest); 1002 1002 1003 1003 if (!hdsa) 1004 1004 return FALSE; 1005 1005 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount)) 1006 1006 return FALSE; 1007 1007 1008 1008 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); … … 1014 1014 1015 1015 /************************************************************************** 1016 * DSA_GetItemPtr [COMCTL32.323] 1016 * DSA_GetItemPtr [COMCTL32.323] 1017 1017 * 1018 1018 * Retrieves a pointer to the specified item. … … 1035 1035 1036 1036 if (!hdsa) 1037 1037 return NULL; 1038 1038 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount)) 1039 1039 return NULL; 1040 1040 1041 1041 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 1042 1042 1043 1043 TRACE("-- ret=%p\n", pSrc); 1044 1044 … … 1048 1048 1049 1049 /************************************************************************** 1050 * DSA_SetItem [COMCTL32.325] 1050 * DSA_SetItem [COMCTL32.325] 1051 1051 * 1052 1052 * Sets the contents of an item in the array. … … 1067 1067 INT nSize, nNewItems; 1068 1068 LPVOID pDest, lpTemp; 1069 1069 1070 1070 TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc); 1071 1071 1072 1072 if ((!hdsa) || nIndex < 0) 1073 1074 1073 return FALSE; 1074 1075 1075 if (hdsa->nItemCount <= nIndex) { 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 } 1076 /* within the old array */ 1077 if (hdsa->nMaxCount > nIndex) { 1078 /* within the allocated space, set a new boundary */ 1079 hdsa->nItemCount = nIndex + 1; 1080 } 1081 else { 1082 /* resize the block of memory */ 1083 nNewItems = 1084 hdsa->nGrow * ((INT)(((nIndex + 1) - 1) / hdsa->nGrow) + 1); 1085 nSize = hdsa->nItemSize * nNewItems; 1086 1087 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize); 1088 if (!lpTemp) 1089 return FALSE; 1090 1091 hdsa->nMaxCount = nNewItems; 1092 hdsa->nItemCount = nIndex + 1; 1093 hdsa->pData = lpTemp; 1094 } 1095 1095 } 1096 1096 … … 1098 1098 pDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 1099 1099 TRACE("-- move dest=%p src=%p size=%d\n", 1100 1100 pDest, pSrc, hdsa->nItemSize); 1101 1101 memmove (pDest, pSrc, hdsa->nItemSize); 1102 1102 … … 1106 1106 1107 1107 /************************************************************************** 1108 * DSA_InsertItem [COMCTL32.324] 1108 * DSA_InsertItem [COMCTL32.324] 1109 1109 * 1110 1110 * PARAMS … … 1124 1124 LPVOID lpTemp, lpDest; 1125 1125 LPDWORD p; 1126 1126 1127 1127 TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc); 1128 1128 1129 1129 if ((!hdsa) || nIndex < 0) 1130 1130 return -1; 1131 1131 1132 1132 for (i = 0; i < hdsa->nItemSize; i += 4) { 1133 1134 1135 1136 1137 1138 } 1139 1133 p = *(DWORD**)((char *) pSrc + i); 1134 if (IsBadStringPtrA ((char*)p, 256)) 1135 TRACE("-- %d=%p\n", i, (DWORD*)p); 1136 else 1137 TRACE("-- %d=%p [%s]\n", i, p, debugstr_a((char*)p)); 1138 } 1139 1140 1140 /* when nIndex >= nItemCount then append */ 1141 1141 if (nIndex >= hdsa->nItemCount) 1142 1142 nIndex = hdsa->nItemCount; 1143 1143 1144 1144 /* do we need to resize ? */ 1145 1145 if (hdsa->nItemCount >= hdsa->nMaxCount) { 1146 1147 1148 1149 1150 1151 1152 1153 1154 hdsa->pData = lpTemp; 1146 nNewItems = hdsa->nMaxCount + hdsa->nGrow; 1147 nSize = hdsa->nItemSize * nNewItems; 1148 1149 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize); 1150 if (!lpTemp) 1151 return -1; 1152 1153 hdsa->nMaxCount = nNewItems; 1154 hdsa->pData = lpTemp; 1155 1155 } 1156 1156 1157 1157 /* do we need to move elements ? */ 1158 1158 if (nIndex < hdsa->nItemCount) { 1159 1160 1161 1162 1163 1164 1159 lpTemp = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 1160 lpDest = (char *) lpTemp + hdsa->nItemSize; 1161 nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize; 1162 TRACE("-- move dest=%p src=%p size=%d\n", 1163 lpDest, lpTemp, nSize); 1164 memmove (lpDest, lpTemp, nSize); 1165 1165 } 1166 1166 … … 1169 1169 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 1170 1170 TRACE("-- move dest=%p src=%p size=%d\n", 1171 1171 lpDest, pSrc, hdsa->nItemSize); 1172 1172 memmove (lpDest, pSrc, hdsa->nItemSize); 1173 1173 … … 1177 1177 1178 1178 /************************************************************************** 1179 * DSA_DeleteItem [COMCTL32.326] 1179 * DSA_DeleteItem [COMCTL32.326] 1180 1180 * 1181 1181 * PARAMS … … 1193 1193 LPVOID lpDest,lpSrc; 1194 1194 INT nSize; 1195 1195 1196 1196 TRACE("(%p %d)\n", hdsa, nIndex); 1197 1197 1198 1198 if (!hdsa) 1199 1199 return -1; 1200 1200 if (nIndex < 0 || nIndex >= hdsa->nItemCount) 1201 1201 return -1; 1202 1202 1203 1203 /* do we need to move ? */ 1204 1204 if (nIndex < hdsa->nItemCount - 1) { 1205 1206 1207 1208 1209 1210 1211 } 1212 1205 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 1206 lpSrc = (char *) lpDest + hdsa->nItemSize; 1207 nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1); 1208 TRACE("-- move dest=%p src=%p size=%d\n", 1209 lpDest, lpSrc, nSize); 1210 memmove (lpDest, lpSrc, nSize); 1211 } 1212 1213 1213 hdsa->nItemCount--; 1214 1214 1215 1215 /* free memory ? */ 1216 1216 if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) { 1217 1218 1219 1220 1221 1222 1223 1224 1217 nSize = hdsa->nItemSize * hdsa->nItemCount; 1218 1219 lpDest = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize); 1220 if (!lpDest) 1221 return -1; 1222 1223 hdsa->nMaxCount = hdsa->nItemCount; 1224 hdsa->pData = lpDest; 1225 1225 } 1226 1226 … … 1247 1247 TRACE("(%p)\n", hdsa); 1248 1248 1249 if (!hdsa) 1250 1249 if (!hdsa) 1250 return FALSE; 1251 1251 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData))) 1252 1252 return FALSE; 1253 1253 1254 1254 hdsa->nItemCount = 0; … … 1285 1285 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA)); 1286 1286 if (hdpa) { 1287 1288 1289 1290 1291 1287 hdpa->nGrow = max(8, nGrow); 1288 hdpa->hHeap = COMCTL32_hHeap; 1289 hdpa->nMaxCount = hdpa->nGrow * 2; 1290 hdpa->ptrs = 1291 (LPVOID*)COMCTL32_Alloc (hdpa->nMaxCount * sizeof(LPVOID)); 1292 1292 } 1293 1293 … … 1315 1315 1316 1316 if (!hdpa) 1317 1317 return FALSE; 1318 1318 1319 1319 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs))) 1320 1320 return FALSE; 1321 1321 1322 1322 return HeapFree (hdpa->hHeap, 0, hdpa); … … 1344 1344 1345 1345 if (!hdpa) 1346 1346 return FALSE; 1347 1347 1348 1348 hdpa->nGrow = max(8, nGrow); … … 1379 1379 1380 1380 if (!hdpa) 1381 1381 return NULL; 1382 1382 1383 1383 TRACE("(%p %p)\n", hdpa, hdpaNew); 1384 1384 1385 1385 if (!hdpaNew) { 1386 1387 1388 1389 1390 1386 /* create a new DPA */ 1387 hdpaTemp = (HDPA)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY, 1388 sizeof(DPA)); 1389 hdpaTemp->hHeap = hdpa->hHeap; 1390 hdpaTemp->nGrow = hdpa->nGrow; 1391 1391 } 1392 1392 else 1393 1393 hdpaTemp = hdpaNew; 1394 1394 1395 1395 if (hdpaTemp->ptrs) { 1396 1397 1398 1399 1400 1396 /* remove old pointer array */ 1397 HeapFree (hdpaTemp->hHeap, 0, hdpaTemp->ptrs); 1398 hdpaTemp->ptrs = NULL; 1399 hdpaTemp->nItemCount = 0; 1400 hdpaTemp->nMaxCount = 0; 1401 1401 } 1402 1402 1403 1403 /* create a new pointer array */ 1404 1404 nNewItems = hdpaTemp->nGrow * 1405 1405 ((INT)((hdpa->nItemCount - 1) / hdpaTemp->nGrow) + 1); 1406 1406 nSize = nNewItems * sizeof(LPVOID); 1407 1407 hdpaTemp->ptrs = 1408 1408 (LPVOID*)HeapAlloc (hdpaTemp->hHeap, HEAP_ZERO_MEMORY, nSize); 1409 1409 hdpaTemp->nMaxCount = nNewItems; 1410 1410 … … 1412 1412 hdpaTemp->nItemCount = hdpa->nItemCount; 1413 1413 memmove (hdpaTemp->ptrs, hdpa->ptrs, 1414 1414 hdpaTemp->nItemCount * sizeof(LPVOID)); 1415 1415 1416 1416 return hdpaTemp; … … 1438 1438 1439 1439 if (!hdpa) 1440 1440 return NULL; 1441 1441 if (!hdpa->ptrs) { 1442 1443 1442 WARN("no pointer array.\n"); 1443 return NULL; 1444 1444 } 1445 1445 if ((i < 0) || (i >= hdpa->nItemCount)) { 1446 1447 1446 WARN("not enough pointers in array (%d vs %d).\n",i,hdpa->nItemCount); 1447 return NULL; 1448 1448 } 1449 1449 … … 1474 1474 1475 1475 if (!hdpa->ptrs) 1476 1476 return -1; 1477 1477 1478 1478 for (i = 0; i < hdpa->nItemCount; i++) { 1479 1480 1479 if (hdpa->ptrs[i] == p) 1480 return i; 1481 1481 } 1482 1482 … … 1509 1509 1510 1510 if ((!hdpa) || (i < 0)) 1511 1511 return -1; 1512 1512 1513 1513 if (!hdpa->ptrs) { 1514 1515 1516 1517 1518 1519 1514 hdpa->ptrs = 1515 (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY, 1516 2 * hdpa->nGrow * sizeof(LPVOID)); 1517 if (!hdpa->ptrs) 1518 return -1; 1519 hdpa->nMaxCount = hdpa->nGrow * 2; 1520 1520 nIndex = 0; 1521 1521 } 1522 1522 else { 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1523 if (hdpa->nItemCount >= hdpa->nMaxCount) { 1524 TRACE("-- resizing\n"); 1525 nNewItems = hdpa->nMaxCount + hdpa->nGrow; 1526 nSize = nNewItems * sizeof(LPVOID); 1527 1528 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY, 1529 hdpa->ptrs, nSize); 1530 if (!lpTemp) 1531 return -1; 1532 hdpa->nMaxCount = nNewItems; 1533 hdpa->ptrs = lpTemp; 1534 } 1535 1536 if (i >= hdpa->nItemCount) { 1537 nIndex = hdpa->nItemCount; 1538 TRACE("-- appending at %d\n", nIndex); 1539 } 1540 else { 1541 TRACE("-- inserting at %d\n", i); 1542 lpTemp = hdpa->ptrs + i; 1543 lpDest = lpTemp + 1; 1544 nSize = (hdpa->nItemCount - i) * sizeof(LPVOID); 1545 TRACE("-- move dest=%p src=%p size=%x\n", 1546 lpDest, lpTemp, nSize); 1547 memmove (lpDest, lpTemp, nSize); 1548 nIndex = i; 1549 } 1550 1550 } 1551 1551 … … 1577 1577 { 1578 1578 LPVOID *lpTemp; 1579 1579 1580 1580 TRACE("(%p %d %p)\n", hdpa, i, p); 1581 1581 1582 1582 if ((!hdpa) || i < 0) 1583 1584 1583 return FALSE; 1584 1585 1585 if (hdpa->nItemCount <= i) { 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 hdpa->ptrs = lpTemp; 1604 } 1586 /* within the old array */ 1587 if (hdpa->nMaxCount > i) { 1588 /* within the allocated space, set a new boundary */ 1589 hdpa->nItemCount = i+1; 1590 } 1591 else { 1592 /* resize the block of memory */ 1593 INT nNewItems = 1594 hdpa->nGrow * ((INT)(((i+1) - 1) / hdpa->nGrow) + 1); 1595 INT nSize = nNewItems * sizeof(LPVOID); 1596 1597 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY, 1598 hdpa->ptrs, nSize); 1599 if (!lpTemp) 1600 return FALSE; 1601 1602 hdpa->nItemCount = nNewItems; 1603 hdpa->ptrs = lpTemp; 1604 } 1605 1605 } 1606 1606 … … 1631 1631 LPVOID *lpDest, *lpSrc, lpTemp = NULL; 1632 1632 INT nSize; 1633 1633 1634 1634 TRACE("(%p %d)\n", hdpa, i); 1635 1635 1636 1636 if ((!hdpa) || i < 0 || i >= hdpa->nItemCount) 1637 1637 return NULL; 1638 1638 1639 1639 lpTemp = hdpa->ptrs[i]; … … 1641 1641 /* do we need to move ?*/ 1642 1642 if (i < hdpa->nItemCount - 1) { 1643 1644 1645 1646 1647 1648 1649 } 1650 1643 lpDest = hdpa->ptrs + i; 1644 lpSrc = lpDest + 1; 1645 nSize = (hdpa->nItemCount - i - 1) * sizeof(LPVOID); 1646 TRACE("-- move dest=%p src=%p size=%x\n", 1647 lpDest, lpSrc, nSize); 1648 memmove (lpDest, lpSrc, nSize); 1649 } 1650 1651 1651 hdpa->nItemCount --; 1652 1652 1653 1653 /* free memory ?*/ 1654 1654 if ((hdpa->nMaxCount - hdpa->nItemCount) >= hdpa->nGrow) { 1655 1656 1657 1658 1659 1660 1661 1662 1663 hdpa->ptrs = (LPVOID*)lpDest; 1655 INT nNewItems = max(hdpa->nGrow * 2, hdpa->nItemCount); 1656 nSize = nNewItems * sizeof(LPVOID); 1657 lpDest = (LPVOID)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY, 1658 hdpa->ptrs, nSize); 1659 if (!lpDest) 1660 return NULL; 1661 1662 hdpa->nMaxCount = nNewItems; 1663 hdpa->ptrs = (LPVOID*)lpDest; 1664 1664 } 1665 1665 … … 1686 1686 TRACE("(%p)\n", hdpa); 1687 1687 1688 if (!hdpa) 1689 1688 if (!hdpa) 1689 return FALSE; 1690 1690 1691 1691 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs))) 1692 1692 return FALSE; 1693 1693 1694 1694 hdpa->nItemCount = 0; 1695 1695 hdpa->nMaxCount = hdpa->nGrow * 2; 1696 1696 hdpa->ptrs = (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY, 1697 1697 hdpa->nMaxCount * sizeof(LPVOID)); 1698 1698 1699 1699 return TRUE; … … 1719 1719 static VOID 1720 1720 DPA_QuickSort (LPVOID *lpPtrs, INT l, INT r, 1721 1721 PFNDPACOMPARE pfnCompare, LPARAM lParam) 1722 1722 { 1723 1723 INT m; … … 1725 1725 1726 1726 TRACE("l=%i r=%i\n", l, r); 1727 1727 1728 1728 if (l==r) /* one element is always sorted */ 1729 1729 return; 1730 1730 if (r<l) /* oops, got it in the wrong order */ 1731 1731 { 1732 1732 DPA_QuickSort(lpPtrs, r, l, pfnCompare, lParam); 1733 1733 return; 1734 1734 } 1735 1735 m = (l+r)/2; /* divide by two */ 1736 1736 DPA_QuickSort(lpPtrs, l, m, pfnCompare, lParam); … … 1738 1738 1739 1739 /* join the two sides */ 1740 while( (l<=m) && (m<r) ) 1740 while( (l<=m) && (m<r) ) 1741 1741 { 1742 1742 if(pfnCompare(lpPtrs[l],lpPtrs[m+1],lParam)>0) … … 1772 1772 { 1773 1773 if (!hdpa || !pfnCompare) 1774 1774 return FALSE; 1775 1775 1776 1776 TRACE("(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam); 1777 1777 1778 1778 if ((hdpa->nItemCount > 1) && (hdpa->ptrs)) 1779 1780 1779 DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1, 1780 pfnCompare, lParam); 1781 1781 1782 1782 return TRUE; … … 1809 1809 INT WINAPI 1810 1810 DPA_Search (const HDPA hdpa, LPVOID pFind, INT nStart, 1811 1811 PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions) 1812 1812 { 1813 1813 if (!hdpa || !pfnCompare || !pFind) 1814 1814 return -1; 1815 1815 1816 1816 TRACE("(%p %p %d %p 0x%08lx 0x%08x)\n", 1817 1817 hdpa, pFind, nStart, pfnCompare, lParam, uOptions); 1818 1818 1819 1819 if (uOptions & DPAS_SORTED) { 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1820 /* array is sorted --> use binary search */ 1821 INT l, r, x, n; 1822 LPVOID *lpPtr; 1823 1824 TRACE("binary search\n"); 1825 1826 l = (nStart == -1) ? 0 : nStart; 1827 r = hdpa->nItemCount - 1; 1828 lpPtr = hdpa->ptrs; 1829 while (r >= l) { 1830 x = (l + r) / 2; 1831 n = (pfnCompare)(pFind, lpPtr[x], lParam); 1832 if (n < 0) 1833 r = x - 1; 1834 else 1835 l = x + 1; 1836 if (n == 0) { 1837 TRACE("-- ret=%d\n", n); 1838 return n; 1839 } 1840 } 1841 1842 if (uOptions & DPAS_INSERTBEFORE) { 1843 TRACE("-- ret=%d\n", r); 1844 return r; 1845 } 1846 1847 if (uOptions & DPAS_INSERTAFTER) { 1848 TRACE("-- ret=%d\n", l); 1849 return l; 1850 } 1851 1851 } 1852 1852 else { 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1853 /* array is not sorted --> use linear search */ 1854 LPVOID *lpPtr; 1855 INT nIndex; 1856 1857 TRACE("linear search\n"); 1858 1859 nIndex = (nStart == -1)? 0 : nStart; 1860 lpPtr = hdpa->ptrs; 1861 for (; nIndex < hdpa->nItemCount; nIndex++) { 1862 if ((pfnCompare)(pFind, lpPtr[nIndex], lParam) == 0) { 1863 TRACE("-- ret=%d\n", nIndex); 1864 return nIndex; 1865 } 1866 } 1867 1867 } 1868 1868 … … 1894 1894 1895 1895 if (hHeap) 1896 1896 hdpa = (HDPA)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, sizeof(DPA)); 1897 1897 else 1898 1898 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA)); 1899 1899 1900 1900 if (hdpa) { 1901 1902 1903 1904 1905 1906 1901 hdpa->nGrow = min(8, nGrow); 1902 hdpa->hHeap = hHeap ? hHeap : COMCTL32_hHeap; 1903 hdpa->nMaxCount = hdpa->nGrow * 2; 1904 hdpa->ptrs = 1905 (LPVOID*)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, 1906 hdpa->nMaxCount * sizeof(LPVOID)); 1907 1907 } 1908 1908 … … 1940 1940 1941 1941 TRACE("(0x%04x 0x%04x %d %p 0x%08lx)\n", 1942 1943 1942 lpNotify->hwndFrom, lpNotify->hwndTo, uCode, lpHdr, 1943 lpNotify->dwParam5); 1944 1944 1945 1945 if (!lpNotify->hwndTo) 1946 1946 return 0; 1947 1947 1948 1948 if (lpNotify->hwndFrom == -1) { 1949 1950 1949 lpNmh = lpHdr; 1950 idFrom = lpHdr->idFrom; 1951 1951 } 1952 1952 else { 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1953 if (lpNotify->hwndFrom) { 1954 HWND hwndParent = GetParent (lpNotify->hwndFrom); 1955 if (hwndParent) { 1956 hwndParent = GetWindow (lpNotify->hwndFrom, GW_OWNER); 1957 if (hwndParent) 1958 idFrom = GetDlgCtrlID (lpNotify->hwndFrom); 1959 } 1960 } 1961 1962 lpNmh = (lpHdr) ? lpHdr : &nmhdr; 1963 1964 lpNmh->hwndFrom = lpNotify->hwndFrom; 1965 lpNmh->idFrom = idFrom; 1966 lpNmh->code = uCode; 1967 1967 } 1968 1968 … … 1987 1987 LRESULT WINAPI 1988 1988 COMCTL32_SendNotify (HWND hwndFrom, HWND hwndTo, 1989 1989 UINT uCode, LPNMHDR lpHdr) 1990 1990 { 1991 1991 NOTIFYDATA notify; 1992 1992 1993 1993 TRACE("(0x%04x 0x%04x %d %p)\n", 1994 1994 hwndFrom, hwndTo, uCode, lpHdr); 1995 1995 1996 1996 notify.hwndFrom = hwndFrom; … … 2020 2020 LRESULT WINAPI 2021 2021 COMCTL32_SendNotifyEx (HWND hwndTo, HWND hwndFrom, UINT uCode, 2022 2022 LPNMHDR lpHdr, DWORD dwParam5) 2023 2023 { 2024 2024 NOTIFYDATA notify; … … 2026 2026 2027 2027 TRACE("(0x%04x 0x%04x %d %p 0x%08lx)\n", 2028 2028 hwndFrom, hwndTo, uCode, lpHdr, dwParam5); 2029 2029 2030 2030 hwndNotify = hwndTo; 2031 2031 if (!hwndTo) { 2032 2033 2034 2035 2036 2032 if (IsWindow (hwndFrom)) { 2033 hwndNotify = GetParent (hwndFrom); 2034 if (!hwndNotify) 2035 return 0; 2036 } 2037 2037 } 2038 2038 … … 2069 2069 2070 2070 if (*lpStr2 == 0) 2071 2071 return ((LPSTR)lpStr1); 2072 2072 len1 = 0; 2073 2073 while (lpStr1[len1] != 0) ++len1; … … 2075 2075 while (lpStr2[len2] != 0) ++len2; 2076 2076 if (len2 == 0) 2077 2077 return ((LPSTR)(lpStr1 + len1)); 2078 2078 first = tolower (*lpStr2); 2079 2079 while (len1 >= len2) { 2080 2081 2082 2083 2084 2085 2080 if (tolower(*lpStr1) == first) { 2081 for (i = 1; i < len2; ++i) 2082 if (tolower (lpStr1[i]) != tolower(lpStr2[i])) 2083 break; 2084 if (i >= len2) 2085 return ((LPSTR)lpStr1); 2086 2086 } 2087 2087 ++lpStr1; --len1; 2088 2088 } 2089 2089 return (NULL); … … 2116 2116 * 2117 2117 * Enumerates all items in a dynamic pointer array. 2118 * 2119 * PARAMS 2120 * hdpa [I] handle to the dynamic pointer array 2121 * enumProc [I] 2122 * lParam [I] 2123 * 2124 * RETURNS 2125 * none 2126 */ 2127 2128 VOID WINAPI 2129 DPA_EnumCallback (const HDPA hdpa, DPAENUMPROC enumProc, LPARAM lParam) 2130 { 2131 INT i; 2132 2133 TRACE("(%p %p %08lx)\n", hdpa, enumProc, lParam); 2134 2135 if (!hdpa) 2136 return; 2137 if (hdpa->nItemCount <= 0) 2138 return; 2139 2140 for (i = 0; i < hdpa->nItemCount; i++) { 2141 if ((enumProc)(hdpa->ptrs[i], lParam) == 0) 2142 return; 2143 } 2144 2145 return; 2146 } 2147 2148 2149 /************************************************************************** 2150 * DPA_DestroyCallback [COMCTL32.386] 2151 * 2152 * Enumerates all items in a dynamic pointer array and destroys it. 2118 2153 * 2119 2154 * PARAMS … … 2123 2158 * 2124 2159 * RETURNS 2125 * none2126 */2127 2128 VOID WINAPI2129 DPA_EnumCallback (const HDPA hdpa, DPAENUMPROC enumProc, LPARAM lParam)2130 {2131 INT i;2132 2133 TRACE("(%p %p %08lx)\n", hdpa, enumProc, lParam);2134 2135 if (!hdpa)2136 return;2137 if (hdpa->nItemCount <= 0)2138 return;2139 2140 for (i = 0; i < hdpa->nItemCount; i++) {2141 if ((enumProc)(hdpa->ptrs[i], lParam) == 0)2142 return;2143 }2144 2145 return;2146 }2147 2148 2149 /**************************************************************************2150 * DPA_DestroyCallback [COMCTL32.386]2151 *2152 * Enumerates all items in a dynamic pointer array and destroys it.2153 *2154 * PARAMS2155 * hdpa [I] handle to the dynamic pointer array2156 * enumProc [I]2157 * lParam [I]2158 *2159 * RETURNS2160 2160 * Success: TRUE 2161 2161 * Failure: FALSE … … 2195 2195 2196 2196 if (!hdsa) 2197 2197 return; 2198 2198 if (hdsa->nItemCount <= 0) 2199 2199 return; 2200 2200 2201 2201 for (i = 0; i < hdsa->nItemCount; i++) { 2202 2203 2204 2202 LPVOID lpItem = DSA_GetItemPtr (hdsa, i); 2203 if ((enumProc)(lpItem, lParam) == 0) 2204 return; 2205 2205 } 2206 2206 … … 2301 2301 if (dbcs && lpStart[1] != HIBYTE(wMatch)) continue; 2302 2302 lpGotIt = lpStart; 2303 } 2303 } 2304 2304 return (LPSTR)lpGotIt; 2305 2305 } … … 2355 2355 if( strchrW(lpSet, *(WORD*)lpLoop)) 2356 2356 return (INT)(lpLoop-lpStr); 2357 2357 2358 2358 return (INT)(lpLoop-lpStr); 2359 2359 } … … 2399 2399 2400 2400 if (IsWindow (hwnd) == FALSE) 2401 2401 return FALSE; 2402 2402 2403 2403 if (b == 0) 2404 2404 return FALSE; 2405 2405 2406 2406 -
trunk/src/comctl32/datetime.c
r6705 r6709 34 34 COMCTL32_HEADER header; 35 35 #endif 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 int *buflen; 54 36 HWND hMonthCal; 37 HWND hUpdown; 38 SYSTEMTIME date; 39 BOOL dateValid; 40 HWND hwndCheckbut; 41 RECT rcClient; /* rect around the edge of the window */ 42 RECT rcDraw; /* rect inside of the border */ 43 RECT checkbox; /* checkbox allowing the control to be enabled/disabled */ 44 RECT calbutton; /* button that toggles the dropdown of the monthcal control */ 45 BOOL bCalDepressed; /* TRUE = cal button is depressed */ 46 int select; 47 HFONT hFont; 48 int nrFieldsAllocated; 49 int nrFields; 50 int haveFocus; 51 int *fieldspec; 52 RECT *fieldRect; 53 int *buflen; 54 char textbuf[256]; 55 55 POINT monthcal_pos; 56 56 } DATETIME_INFO, *LPDATETIME_INFO; … … 61 61 /* this list of defines is closely related to `allowedformatchars' defined 62 62 * in datetime.c; the high nibble indicates the `base type' of the format 63 * specifier. 63 * specifier. 64 64 * Do not change without first reading DATETIME_UseFormat. 65 * 65 * 66 66 */ 67 67 68 #define DT_END_FORMAT 0 69 #define ONEDIGITDAY 70 #define TWODIGITDAY 71 #define THREECHARDAY 68 #define DT_END_FORMAT 0 69 #define ONEDIGITDAY 0x01 70 #define TWODIGITDAY 0x02 71 #define THREECHARDAY 0x03 72 72 #define FULLDAY 0x04 73 73 #define ONEDIGIT12HOUR 0x11 … … 94 94 #define FORMATCALLBACK 0x81 /* -> maximum of 0x80 callbacks possible */ 95 95 #define FORMATCALLMASK 0x80 96 #define DT_STRING 96 #define DT_STRING 0x0100 97 97 98 98 #define DTHT_DATEFIELD 0xff /* for hit-testing */ 99 99 100 100 #define DTHT_NONE 0 101 #define DTHT_CHECKBOX 0x200 101 #define DTHT_CHECKBOX 0x200 /* these should end at '00' , to make */ 102 102 #define DTHT_MCPOPUP 0x300 /* & DTHT_DATEFIELD 0 when DATETIME_KeyDown */ 103 103 #define DTHT_GOTFOCUS 0x400 /* tests for date-fields */ … … 126 126 if (!lParam) return GDT_NONE; 127 127 128 if ((dwStyle & DTS_SHOWNONE) && 128 if ((dwStyle & DTS_SHOWNONE) && 129 129 (SendMessageA (infoPtr->hwndCheckbut, BM_GETCHECK, 0, 0))) 130 130 return GDT_NONE; … … 145 145 if (!lParam) return 0; 146 146 147 if (lParam==GDT_VALID) 148 147 if (lParam==GDT_VALID) 148 MONTHCAL_CopyTime (lprgSysTimeArray, &infoPtr->date); 149 149 if (lParam==GDT_NONE) { 150 150 infoPtr->dateValid=FALSE; 151 151 SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, 0, 0); 152 152 } 153 153 return 1; 154 154 } … … 228 228 229 229 230 /* 231 Split up a formattxt in actions. 230 /* 231 Split up a formattxt in actions. 232 232 See ms documentation for the meaning of the letter codes/'specifiers'. 233 233 234 Notes: 234 Notes: 235 235 *'dddddd' is handled as 'dddd' plus 'dd'. 236 *unrecognized formats are strings (here given the type DT_STRING; 236 *unrecognized formats are strings (here given the type DT_STRING; 237 237 start of the string is encoded in lower bits of DT_STRING. 238 238 Therefore, 'string' ends finally up as '<show seconds>tring'. … … 241 241 242 242 243 static void 243 static void 244 244 DATETIME_UseFormat (DATETIME_INFO *infoPtr, const char *formattxt) 245 245 { … … 256 256 257 257 for (i=0; i<strlen (formattxt); i++) { 258 259 260 if (allowedformatchars[j]==formattxt[i]) {261 262 263 264 265 266 267 if (infoPtr->fieldspec[*nrFields]>>4!=j) { 268 (*nrFields)++; 269 270 271 272 273 (*nrFields)++; 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 } else 289 290 291 292 293 } 294 295 296 297 298 299 300 301 258 TRACE ("\n%d %c:",i, formattxt[i]); 259 for (j=0; j<len; j++) { 260 if (allowedformatchars[j]==formattxt[i]) { 261 TRACE ("%c[%d,%x]",allowedformatchars[j], *nrFields, 262 infoPtr->fieldspec[*nrFields]); 263 if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) { 264 infoPtr->fieldspec[*nrFields]=(j<<4) +1; 265 break; 266 } 267 if (infoPtr->fieldspec[*nrFields]>>4!=j) { 268 (*nrFields)++; 269 infoPtr->fieldspec[*nrFields]=(j<<4) +1; 270 break; 271 } 272 if ((infoPtr->fieldspec[*nrFields] & 0x0f)==maxrepetition[j]) { 273 (*nrFields)++; 274 infoPtr->fieldspec[*nrFields]=(j<<4) +1; 275 break; 276 } 277 infoPtr->fieldspec[*nrFields]++; 278 break; 279 } /* if allowedformatchar */ 280 } /* for j */ 281 282 283 /* char is not a specifier: handle char like a string */ 284 if (j==len) { 285 if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) { 286 infoPtr->fieldspec[*nrFields]=DT_STRING+k; 287 infoPtr->buflen[*nrFields]=0; 288 } else 289 if ((infoPtr->fieldspec[*nrFields] & DT_STRING)!=DT_STRING) { 290 (*nrFields)++; 291 infoPtr->fieldspec[*nrFields]=DT_STRING+k; 292 infoPtr->buflen[*nrFields]=0; 293 } 294 infoPtr->textbuf[k]=formattxt[i]; 295 k++; 296 infoPtr->buflen[*nrFields]++; 297 } /* if j=len */ 298 299 if (*nrFields==infoPtr->nrFieldsAllocated) { 300 FIXME ("out of memory; should reallocate. crash ahead.\n"); 301 } 302 302 303 303 } /* for i */ … … 309 309 310 310 311 static LRESULT 311 static LRESULT 312 312 DATETIME_SetFormat (HWND hwnd, WPARAM wParam, LPARAM lParam) 313 313 { … … 318 318 TRACE("%04x %08lx\n",wParam,lParam); 319 319 if (!lParam) { 320 321 322 if (dwStyle & DTS_LONGDATEFORMAT) 323 324 else if (dwStyle & DTS_TIMEFORMAT) 325 320 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE); 321 322 if (dwStyle & DTS_LONGDATEFORMAT) 323 format_item=LOCALE_SLONGDATE; 324 else if (dwStyle & DTS_TIMEFORMAT) 325 format_item=LOCALE_STIMEFORMAT; 326 326 else /* DTS_SHORTDATEFORMAT */ 327 328 329 330 } 327 format_item=LOCALE_SSHORTDATE; 328 GetLocaleInfoA( GetSystemDefaultLCID(), format_item,format_buf,sizeof(format_buf)); 329 DATETIME_UseFormat (infoPtr, format_buf); 330 } 331 331 else 332 332 DATETIME_UseFormat (infoPtr, (char *) lParam); 333 333 334 334 return infoPtr->nrFields; … … 336 336 337 337 338 static LRESULT 338 static LRESULT 339 339 DATETIME_SetFormatW (HWND hwnd, WPARAM wParam, LPARAM lParam) 340 340 … … 342 342 TRACE("%04x %08lx\n",wParam,lParam); 343 343 if (lParam) { 344 345 344 LPSTR buf; 345 int retval; 346 346 int len = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, NULL, 0, NULL, NULL ); 347 347 348 348 buf = (LPSTR) COMCTL32_Alloc (len); 349 349 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, buf, len, NULL, NULL ); 350 351 352 353 } 350 retval=DATETIME_SetFormat (hwnd, 0, (LPARAM) buf); 351 COMCTL32_Free (buf); 352 return retval; 353 } 354 354 else 355 356 357 } 358 359 360 static void 355 return DATETIME_SetFormat (hwnd, 0, 0); 356 357 } 358 359 360 static void 361 361 DATETIME_ReturnTxt (DATETIME_INFO *infoPtr, int count, char *result) 362 362 { … … 368 368 TRACE ("%d,%d\n", infoPtr->nrFields, count); 369 369 if ((count>infoPtr->nrFields) || (count<0)) { 370 371 370 WARN ("buffer overrun, have %d want %d\n", infoPtr->nrFields, count); 371 return; 372 372 } 373 373 374 374 if (!infoPtr->fieldspec) return; 375 375 376 376 spec=infoPtr->fieldspec[count]; 377 377 if (spec & DT_STRING) { 378 379 380 381 382 383 378 int txtlen=infoPtr->buflen[count]; 379 380 strncpy (result, infoPtr->textbuf + (spec &~ DT_STRING), txtlen); 381 result[txtlen]=0; 382 TRACE ("arg%d=%x->[%s]\n",count,infoPtr->fieldspec[count],result); 383 return; 384 384 } 385 385 386 386 387 387 switch (spec) { 388 case DT_END_FORMAT: 389 390 391 case ONEDIGITDAY: 392 393 394 case TWODIGITDAY: 395 396 397 case THREECHARDAY: 398 399 400 401 402 403 404 405 406 407 case ONEDIGIT12HOUR: 408 if (date.wHour>12) 409 410 else 411 412 413 case TWODIGIT12HOUR: 414 if (date.wHour>12) 415 416 else 417 418 419 case ONEDIGIT24HOUR: 420 421 422 case TWODIGIT24HOUR: 423 424 425 case ONEDIGITSECOND: 426 427 428 case TWODIGITSECOND: 429 430 431 case ONEDIGITMINUTE: 432 433 434 case TWODIGITMINUTE: 435 436 437 case ONEDIGITMONTH: 438 439 440 case TWODIGITMONTH: 441 442 443 case THREECHARMONTH: 444 445 446 447 448 case FULLMONTH: 449 388 case DT_END_FORMAT: 389 *result=0; 390 break; 391 case ONEDIGITDAY: 392 sprintf (result,"%d",date.wDay); 393 break; 394 case TWODIGITDAY: 395 sprintf (result,"%.2d",date.wDay); 396 break; 397 case THREECHARDAY: 398 GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1+(date.wDayOfWeek+6)%7, 399 result,4); 400 /*sprintf (result,"%.3s",days[date.wDayOfWeek]);*/ 401 break; 402 case FULLDAY: 403 GetLocaleInfoA( LOCALE_USER_DEFAULT,LOCALE_SDAYNAME1+ (date.wDayOfWeek+6)%7, 404 buffer,sizeof(buffer)); 405 strcpy (result,buffer); 406 break; 407 case ONEDIGIT12HOUR: 408 if (date.wHour>12) 409 sprintf (result,"%d",date.wHour-12); 410 else 411 sprintf (result,"%d",date.wHour); 412 break; 413 case TWODIGIT12HOUR: 414 if (date.wHour>12) 415 sprintf (result,"%.2d",date.wHour-12); 416 else 417 sprintf (result,"%.2d",date.wHour); 418 break; 419 case ONEDIGIT24HOUR: 420 sprintf (result,"%d",date.wHour); 421 break; 422 case TWODIGIT24HOUR: 423 sprintf (result,"%.2d",date.wHour); 424 break; 425 case ONEDIGITSECOND: 426 sprintf (result,"%d",date.wSecond); 427 break; 428 case TWODIGITSECOND: 429 sprintf (result,"%.2d",date.wSecond); 430 break; 431 case ONEDIGITMINUTE: 432 sprintf (result,"%d",date.wMinute); 433 break; 434 case TWODIGITMINUTE: 435 sprintf (result,"%.2d",date.wMinute); 436 break; 437 case ONEDIGITMONTH: 438 sprintf (result,"%d",date.wMonth); 439 break; 440 case TWODIGITMONTH: 441 sprintf (result,"%.2d",date.wMonth); 442 break; 443 case THREECHARMONTH: 444 GetLocaleInfoA( GetSystemDefaultLCID(),LOCALE_SMONTHNAME1+date.wMonth -1, 445 buffer,sizeof(buffer)); 446 sprintf (result,"%.3s",buffer); 447 break; 448 case FULLMONTH: 449 GetLocaleInfoA( GetSystemDefaultLCID(),LOCALE_SMONTHNAME1+date.wMonth -1, 450 450 #ifdef __WIN32OS2__ 451 452 451 buffer,sizeof(buffer)); 452 strcpy (result,buffer); 453 453 #else 454 454 result,sizeof(result)); 455 455 #endif 456 457 case ONELETTERAMPM: 458 if (date.wHour<12) 459 460 else 461 462 463 case TWOLETTERAMPM: 464 if (date.wHour<12) 465 466 else 467 468 469 case FORMATCALLBACK: 470 471 472 473 case ONEDIGITYEAR: 474 475 476 case TWODIGITYEAR: 477 478 479 case FULLYEAR: 480 481 456 break; 457 case ONELETTERAMPM: 458 if (date.wHour<12) 459 strcpy (result,"A"); 460 else 461 strcpy (result,"P"); 462 break; 463 case TWOLETTERAMPM: 464 if (date.wHour<12) 465 strcpy (result,"AM"); 466 else 467 strcpy (result,"PM"); 468 break; 469 case FORMATCALLBACK: 470 FIXME ("Not implemented\n"); 471 strcpy (result,"xxx"); 472 break; 473 case ONEDIGITYEAR: 474 sprintf (result,"%d",date.wYear-10* (int) floor(date.wYear/10)); 475 break; 476 case TWODIGITYEAR: 477 sprintf (result,"%.2d",date.wYear-100* (int) floor(date.wYear/100)); 478 break; 479 case FULLYEAR: 480 sprintf (result,"%d",date.wYear); 481 break; 482 482 } 483 484 485 } 486 487 488 static void 483 484 TRACE ("arg%d=%x->[%s]\n",count,infoPtr->fieldspec[count],result); 485 } 486 487 488 static void 489 489 DATETIME_IncreaseField (DATETIME_INFO *infoPtr, int number) 490 490 { … … 497 497 spec=infoPtr->fieldspec[number]; 498 498 if ((spec & DTHT_DATEFIELD)==0) return; 499 499 500 500 switch (spec) { 501 case ONEDIGITDAY: 502 case TWODIGITDAY: 503 case THREECHARDAY: 504 505 506 507 date->wDay=1; 508 509 case ONEDIGIT12HOUR: 510 case TWODIGIT12HOUR: 511 case ONEDIGIT24HOUR: 512 case TWODIGIT24HOUR: 513 514 515 516 case ONEDIGITSECOND: 517 case TWODIGITSECOND: 518 519 520 521 case ONEDIGITMINUTE: 522 case TWODIGITMINUTE: 523 524 525 526 case ONEDIGITMONTH: 527 case TWODIGITMONTH: 528 case THREECHARMONTH: 529 case FULLMONTH: 530 531 532 if (date->wDay>MONTHCAL_MonthLength(date->wMonth,date->wYear)) 533 534 535 case ONELETTERAMPM: 536 case TWOLETTERAMPM: 537 538 539 540 case FORMATCALLBACK: 541 542 543 case ONEDIGITYEAR: 544 case TWODIGITYEAR: 545 case FULLYEAR: 546 547 548 549 550 } 551 552 553 static void 501 case ONEDIGITDAY: 502 case TWODIGITDAY: 503 case THREECHARDAY: 504 case FULLDAY: 505 date->wDay++; 506 if (date->wDay>MONTHCAL_MonthLength(date->wMonth,date->wYear)) 507 date->wDay=1; 508 break; 509 case ONEDIGIT12HOUR: 510 case TWODIGIT12HOUR: 511 case ONEDIGIT24HOUR: 512 case TWODIGIT24HOUR: 513 date->wHour++; 514 if (date->wHour>23) date->wHour=0; 515 break; 516 case ONEDIGITSECOND: 517 case TWODIGITSECOND: 518 date->wSecond++; 519 if (date->wSecond>59) date->wSecond=0; 520 break; 521 case ONEDIGITMINUTE: 522 case TWODIGITMINUTE: 523 date->wMinute++; 524 if (date->wMinute>59) date->wMinute=0; 525 break; 526 case ONEDIGITMONTH: 527 case TWODIGITMONTH: 528 case THREECHARMONTH: 529 case FULLMONTH: 530 date->wMonth++; 531 if (date->wMonth>12) date->wMonth=1; 532 if (date->wDay>MONTHCAL_MonthLength(date->wMonth,date->wYear)) 533 date->wDay=MONTHCAL_MonthLength(date->wMonth,date->wYear); 534 break; 535 case ONELETTERAMPM: 536 case TWOLETTERAMPM: 537 date->wHour+=12; 538 if (date->wHour>23) date->wHour-=24; 539 break; 540 case FORMATCALLBACK: 541 FIXME ("Not implemented\n"); 542 break; 543 case ONEDIGITYEAR: 544 case TWODIGITYEAR: 545 case FULLYEAR: 546 date->wYear++; 547 break; 548 } 549 550 } 551 552 553 static void 554 554 DATETIME_DecreaseField (DATETIME_INFO *infoPtr, int number) 555 555 { … … 562 562 spec = infoPtr->fieldspec[number]; 563 563 if ((spec & DTHT_DATEFIELD)==0) return; 564 564 565 565 TRACE ("%x\n",spec); 566 566 567 567 switch (spec) { 568 case ONEDIGITDAY: 569 case TWODIGITDAY: 570 case THREECHARDAY: 571 572 573 if (date->wDay<1) 574 575 576 case ONEDIGIT12HOUR: 577 case TWODIGIT12HOUR: 578 case ONEDIGIT24HOUR: 579 case TWODIGIT24HOUR: 580 if (date->wHour) 581 582 583 584 585 case ONEDIGITSECOND: 586 case TWODIGITSECOND: 587 if (date->wHour) 588 589 590 591 592 case ONEDIGITMINUTE: 593 case TWODIGITMINUTE: 594 if (date->wMinute) 595 596 597 598 599 case ONEDIGITMONTH: 600 case TWODIGITMONTH: 601 case THREECHARMONTH: 602 case FULLMONTH: 603 if (date->wMonth>1) 604 605 606 607 if (date->wDay>MONTHCAL_MonthLength(date->wMonth,date->wYear)) 608 609 610 case ONELETTERAMPM: 611 case TWOLETTERAMPM: 612 if (date->wHour<12) 613 614 615 616 617 case FORMATCALLBACK: 618 619 620 case ONEDIGITYEAR: 621 case TWODIGITYEAR: 622 case FULLYEAR: 623 624 625 626 627 } 628 629 630 static void 568 case ONEDIGITDAY: 569 case TWODIGITDAY: 570 case THREECHARDAY: 571 case FULLDAY: 572 date->wDay--; 573 if (date->wDay<1) 574 date->wDay=MONTHCAL_MonthLength(date->wMonth,date->wYear); 575 break; 576 case ONEDIGIT12HOUR: 577 case TWODIGIT12HOUR: 578 case ONEDIGIT24HOUR: 579 case TWODIGIT24HOUR: 580 if (date->wHour) 581 date->wHour--; 582 else 583 date->wHour=23; 584 break; 585 case ONEDIGITSECOND: 586 case TWODIGITSECOND: 587 if (date->wHour) 588 date->wSecond--; 589 else 590 date->wHour=59; 591 break; 592 case ONEDIGITMINUTE: 593 case TWODIGITMINUTE: 594 if (date->wMinute) 595 date->wMinute--; 596 else 597 date->wMinute=59; 598 break; 599 case ONEDIGITMONTH: 600 case TWODIGITMONTH: 601 case THREECHARMONTH: 602 case FULLMONTH: 603 if (date->wMonth>1) 604 date->wMonth--; 605 else 606 date->wMonth=12; 607 if (date->wDay>MONTHCAL_MonthLength(date->wMonth,date->wYear)) 608 date->wDay=MONTHCAL_MonthLength(date->wMonth,date->wYear); 609 break; 610 case ONELETTERAMPM: 611 case TWOLETTERAMPM: 612 if (date->wHour<12) 613 date->wHour+=12; 614 else 615 date->wHour-=12; 616 break; 617 case FORMATCALLBACK: 618 FIXME ("Not implemented\n"); 619 break; 620 case ONEDIGITYEAR: 621 case TWODIGITYEAR: 622 case FULLYEAR: 623 date->wYear--; 624 break; 625 } 626 627 } 628 629 630 static void 631 631 DATETIME_ResetFieldDown (DATETIME_INFO *infoPtr, int number) 632 632 { … … 639 639 spec = infoPtr->fieldspec[number]; 640 640 if ((spec & DTHT_DATEFIELD)==0) return; 641 641 642 642 643 643 switch (spec) { 644 case ONEDIGITDAY: 645 case TWODIGITDAY: 646 case THREECHARDAY: 647 648 649 650 case ONEDIGIT12HOUR: 651 case TWODIGIT12HOUR: 652 case ONEDIGIT24HOUR: 653 case TWODIGIT24HOUR: 654 case ONELETTERAMPM: 655 case TWOLETTERAMPM: 656 657 658 case ONEDIGITSECOND: 659 case TWODIGITSECOND: 660 661 662 case ONEDIGITMINUTE: 663 case TWODIGITMINUTE: 664 665 666 case ONEDIGITMONTH: 667 case TWODIGITMONTH: 668 case THREECHARMONTH: 669 case FULLMONTH: 670 671 case FORMATCALLBACK: 672 673 674 case ONEDIGITYEAR: 675 case TWODIGITYEAR: 644 case ONEDIGITDAY: 645 case TWODIGITDAY: 646 case THREECHARDAY: 647 case FULLDAY: 648 date->wDay = 1; 649 break; 650 case ONEDIGIT12HOUR: 651 case TWODIGIT12HOUR: 652 case ONEDIGIT24HOUR: 653 case TWODIGIT24HOUR: 654 case ONELETTERAMPM: 655 case TWOLETTERAMPM: 656 date->wHour = 0; 657 break; 658 case ONEDIGITSECOND: 659 case TWODIGITSECOND: 660 date->wSecond = 0; 661 break; 662 case ONEDIGITMINUTE: 663 case TWODIGITMINUTE: 664 date->wMinute = 0; 665 break; 666 case ONEDIGITMONTH: 667 case TWODIGITMONTH: 668 case THREECHARMONTH: 669 case FULLMONTH: 670 date->wMonth = 1; 671 case FORMATCALLBACK: 672 FIXME ("Not implemented\n"); 673 break; 674 case ONEDIGITYEAR: 675 case TWODIGITYEAR: 676 676 /* FYI: On 9/14/1752 the calender changed and England and the American */ 677 677 /* colonies changed to the Gregorian calender. This change involved */ 678 678 /* having September 14th following September 2nd. So no date algorithms */ 679 679 /* work before that date. */ 680 case FULLYEAR: 681 682 683 684 date->wDay = 14;/* overactive ms-programmers..*/685 686 687 688 689 690 } 691 692 693 static void 680 case FULLYEAR: 681 date->wSecond = 0; 682 date->wMinute = 0; 683 date->wHour = 0; 684 date->wDay = 14; /* overactive ms-programmers..*/ 685 date->wMonth = 9; 686 date->wYear = 1752; 687 break; 688 } 689 690 } 691 692 693 static void 694 694 DATETIME_ResetFieldUp (DATETIME_INFO *infoPtr, int number) 695 695 { … … 702 702 spec=infoPtr->fieldspec[number]; 703 703 if ((spec & DTHT_DATEFIELD)==0) return; 704 704 705 705 switch (spec) { 706 case ONEDIGITDAY: 707 case TWODIGITDAY: 708 case THREECHARDAY: 709 710 711 712 case ONEDIGIT12HOUR: 713 case TWODIGIT12HOUR: 714 case ONEDIGIT24HOUR: 715 case TWODIGIT24HOUR: 716 case ONELETTERAMPM: 717 case TWOLETTERAMPM: 718 719 720 case ONEDIGITSECOND: 721 case TWODIGITSECOND: 722 723 724 case ONEDIGITMINUTE: 725 case TWODIGITMINUTE: 726 727 728 case ONEDIGITMONTH: 729 case TWODIGITMONTH: 730 case THREECHARMONTH: 731 case FULLMONTH: 732 733 case FORMATCALLBACK: 734 735 736 case ONEDIGITYEAR: 737 case TWODIGITYEAR: 738 case FULLYEAR: 739 740 741 706 case ONEDIGITDAY: 707 case TWODIGITDAY: 708 case THREECHARDAY: 709 case FULLDAY: 710 date->wDay=MONTHCAL_MonthLength(date->wMonth,date->wYear); 711 break; 712 case ONEDIGIT12HOUR: 713 case TWODIGIT12HOUR: 714 case ONEDIGIT24HOUR: 715 case TWODIGIT24HOUR: 716 case ONELETTERAMPM: 717 case TWOLETTERAMPM: 718 date->wHour=23; 719 break; 720 case ONEDIGITSECOND: 721 case TWODIGITSECOND: 722 date->wSecond=59; 723 break; 724 case ONEDIGITMINUTE: 725 case TWODIGITMINUTE: 726 date->wMinute=59; 727 break; 728 case ONEDIGITMONTH: 729 case TWODIGITMONTH: 730 case THREECHARMONTH: 731 case FULLMONTH: 732 date->wMonth=12; 733 case FORMATCALLBACK: 734 FIXME ("Not implemented\n"); 735 break; 736 case ONEDIGITYEAR: 737 case TWODIGITYEAR: 738 case FULLYEAR: 739 date->wYear=9999; /* Y10K problem? naaah. */ 740 break; 741 } 742 742 743 743 } … … 758 758 SIZE size; 759 759 COLORREF oldBk, oldTextColor; 760 760 761 761 /* draw control edge */ 762 762 TRACE("\n"); … … 764 764 FillRect(hdc, rcClient, hbr); 765 765 DrawEdge(hdc, rcClient, EDGE_SUNKEN, BF_RECT); 766 DeleteObject(hbr); 767 766 DeleteObject(hbr); 767 768 768 if (infoPtr->dateValid) { 769 769 char txt[80]; … … 798 798 DT_RIGHT | DT_VCENTER | DT_SINGLELINE ); 799 799 SetBkColor (hdc, oldBk); 800 800 SetTextColor (hdc, oldTextColor); 801 801 } 802 802 else … … 832 832 if (PtInRect (&infoPtr->fieldRect[i], pt)) { 833 833 retval = i; 834 TRACE("Hit in date text in field %d\n", i); 834 TRACE("Hit in date text in field %d\n", i); 835 835 break; 836 836 } … … 845 845 DATETIME_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam) 846 846 { 847 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 847 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 848 848 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE); 849 849 int old, new; … … 874 874 infoPtr->monthcal_pos.x = infoPtr->rcClient.right - ((infoPtr->calbutton.right - 875 875 infoPtr->calbutton.left) + 145); 876 else 876 else 877 877 infoPtr->monthcal_pos.x = 8; 878 878 … … 888 888 889 889 TRACE ("dt:%x mc:%x mc parent:%x, desktop:%x, mcpp:%x\n", 890 hwnd,infoPtr->hMonthCal, 890 hwnd,infoPtr->hMonthCal, 891 891 GetParent (infoPtr->hMonthCal), 892 892 GetDesktopWindow (), … … 904 904 DATETIME_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) 905 905 { 906 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 906 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 907 907 908 908 TRACE("\n"); 909 909 910 910 if(infoPtr->bCalDepressed == TRUE) { 911 911 infoPtr->bCalDepressed = FALSE; … … 934 934 DATETIME_ParentNotify (HWND hwnd, WPARAM wParam, LPARAM lParam) 935 935 { 936 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 936 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 937 937 LPNMHDR lpnmh = (LPNMHDR) lParam; 938 938 … … 954 954 955 955 { 956 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 956 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 957 957 LPNMHDR lpnmh = (LPNMHDR) lParam; 958 958 … … 964 964 965 965 966 static LRESULT 966 static LRESULT 967 967 DATETIME_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam) 968 968 { … … 978 978 979 979 if (infoPtr->select & FORMATCALLMASK) { 980 980 FIXME ("Callbacks not implemented yet\n"); 981 981 } 982 982 983 983 switch (wParam) { 984 case VK_ADD: 985 case VK_UP: 986 DATETIME_IncreaseField (infoPtr,FieldNum); 987 DATETIME_SendDateTimeChangeNotify (hwnd); 988 break; 989 case VK_SUBTRACT: 990 case VK_DOWN: 991 DATETIME_DecreaseField (infoPtr,FieldNum); 992 DATETIME_SendDateTimeChangeNotify (hwnd); 993 break; 994 case VK_HOME: 995 DATETIME_ResetFieldDown (infoPtr,FieldNum); 996 DATETIME_SendDateTimeChangeNotify (hwnd); 997 break; 998 case VK_END: 999 DATETIME_ResetFieldUp(infoPtr,FieldNum); 1000 DATETIME_SendDateTimeChangeNotify (hwnd); 1001 break; 1002 case VK_LEFT: 1003 do { 1004 if (infoPtr->select==0) { 1005 infoPtr->select = infoPtr->nrFields - 1; 1006 wrap++; 1007 } else 1008 infoPtr->select--; 1009 } 1010 while ((infoPtr->fieldspec[infoPtr->select] & DT_STRING) && (wrap<2)); 1011 break; 1012 case VK_RIGHT: 1013 do { 1014 infoPtr->select++; 1015 if (infoPtr->select==infoPtr->nrFields) { 1016 infoPtr->select = 0; 1017 wrap++; 1018 } 1019 } 1020 while ((infoPtr->fieldspec[infoPtr->select] & DT_STRING) && (wrap<2)); 1021 break; 984 case VK_ADD: 985 case VK_UP: 986 DATETIME_IncreaseField (infoPtr,FieldNum); 987 DATETIME_SendDateTimeChangeNotify (hwnd); 988 break; 989 case VK_SUBTRACT: 990 case VK_DOWN: 991 DATETIME_DecreaseField (infoPtr,FieldNum); 992 DATETIME_SendDateTimeChangeNotify (hwnd); 993 break; 994 case VK_HOME: 995 DATETIME_ResetFieldDown (infoPtr,FieldNum); 996 DATETIME_SendDateTimeChangeNotify (hwnd); 997 break; 998 case VK_END: 999 DATETIME_ResetFieldUp(infoPtr,FieldNum); 1000 DATETIME_SendDateTimeChangeNotify (hwnd); 1001 break; 1002 case VK_LEFT: 1003 do { 1004 if (infoPtr->select==0) { 1005 infoPtr->select = infoPtr->nrFields - 1; 1006 wrap++; 1007 } else 1008 infoPtr->select--; 1009 } 1010 while ((infoPtr->fieldspec[infoPtr->select] & DT_STRING) && (wrap<2)); 1011 break; 1012 case VK_RIGHT: 1013 do { 1014 infoPtr->select++; 1015 if (infoPtr->select==infoPtr->nrFields) { 1016 infoPtr->select = 0; 1017 wrap++; 1018 } 1019 } 1020 while ((infoPtr->fieldspec[infoPtr->select] & DT_STRING) && (wrap<2)); 1021 break; 1022 } 1023 1024 InvalidateRect(hwnd, NULL, FALSE); 1025 1026 return 0; 1027 } 1028 1029 1030 static LRESULT 1031 DATETIME_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam) 1032 { 1033 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 1034 1035 TRACE ("\n"); 1036 1037 if (infoPtr->haveFocus) { 1038 DATETIME_SendSimpleNotify (hwnd, NM_KILLFOCUS); 1039 infoPtr->haveFocus = 0; 1022 1040 } 1023 1041 1024 InvalidateRect(hwnd, NULL, FALSE);1025 1026 return 0;1027 } 1028 1029 1030 static LRESULT 1031 DATETIME_ KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)1032 { 1033 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 1042 InvalidateRect (hwnd, NULL, TRUE); 1043 1044 return 0; 1045 } 1046 1047 1048 static LRESULT 1049 DATETIME_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam) 1050 { 1051 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 1034 1052 1035 1053 TRACE ("\n"); 1036 1054 1037 if (infoPtr->haveFocus) {1038 DATETIME_SendSimpleNotify (hwnd, NM_KILLFOCUS);1039 infoPtr->haveFocus = 0;1040 }1041 1042 InvalidateRect (hwnd, NULL, TRUE);1043 1044 return 0;1045 }1046 1047 1048 static LRESULT1049 DATETIME_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)1050 {1051 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);1052 1053 TRACE ("\n");1054 1055 1055 if (infoPtr->haveFocus==0) { 1056 DATETIME_SendSimpleNotify (hwnd, NM_SETFOCUS); 1057 1056 DATETIME_SendSimpleNotify (hwnd, NM_SETFOCUS); 1057 infoPtr->haveFocus = DTHT_GOTFOCUS; 1058 1058 } 1059 1059 … … 1068 1068 1069 1069 { 1070 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 1070 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 1071 1071 NMDATETIMECHANGE dtdtc; 1072 1072 … … 1136 1136 infoPtr->monthcal_pos.x = infoPtr->rcClient.right - ((infoPtr->calbutton.right - 1137 1137 infoPtr->calbutton.left) + 145); 1138 else 1138 else 1139 1139 infoPtr->monthcal_pos.x = 8; 1140 1140 … … 1172 1172 1173 1173 if (dwStyle & DTS_SHOWNONE) { 1174 infoPtr->hwndCheckbut=CreateWindowExA (0,"button", 0, 1175 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 1174 infoPtr->hwndCheckbut=CreateWindowExA (0,"button", 0, 1175 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 1176 1176 2,2,13,13, 1177 hwnd, 1177 hwnd, 1178 1178 0, GetWindowLongA (hwnd, GWL_HINSTANCE), 0); 1179 1179 SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, 1, 0); … … 1196 1196 1197 1197 /* create the monthcal control */ 1198 infoPtr->hMonthCal = CreateWindowExA (0,"SysMonthCal32", 0, 1199 1200 1201 GetParent(hwnd), 1202 1198 infoPtr->hMonthCal = CreateWindowExA (0,"SysMonthCal32", 0, 1199 WS_BORDER | WS_POPUP | WS_CLIPSIBLINGS, 1200 0, 0, 0, 0, 1201 GetParent(hwnd), 1202 0, 0, 0); 1203 1203 1204 1204 /* initialize info structure */ … … 1214 1214 { 1215 1215 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd); 1216 1216 1217 1217 TRACE("\n"); 1218 1218 COMCTL32_Free (infoPtr); … … 1227 1227 1228 1228 if (!DATETIME_GetInfoPtr(hwnd) && (uMsg != WM_CREATE)) 1229 1230 1229 return DefWindowProcA( hwnd, uMsg, wParam, lParam ); 1230 1231 1231 switch (uMsg) 1232 1232 { … … 1236 1236 1237 1237 case DTM_SETSYSTEMTIME: 1238 1238 return DATETIME_SetSystemTime (hwnd, wParam, lParam); 1239 1239 1240 1240 case DTM_GETRANGE: … … 1266 1266 1267 1267 case WM_PARENTNOTIFY: 1268 1268 return DATETIME_ParentNotify (hwnd, wParam, lParam); 1269 1269 1270 1270 case WM_NOTIFY: 1271 1271 return DATETIME_Notify (hwnd, wParam, lParam); 1272 1272 1273 1273 case WM_GETDLGCODE: … … 1296 1296 1297 1297 case WM_CREATE: 1298 1298 return DATETIME_Create (hwnd, wParam, lParam); 1299 1299 1300 1300 case WM_DESTROY: 1301 1301 return DATETIME_Destroy (hwnd, wParam, lParam); 1302 1302 1303 1303 default: 1304 1305 1306 1304 if (uMsg >= WM_USER) 1305 ERR("unknown msg %04x wp=%08x lp=%08lx\n", 1306 uMsg, wParam, lParam); 1307 1307 #ifdef __WIN32OS2__ 1308 1308 return defComCtl32ProcA (hwnd, uMsg, wParam, lParam); 1309 1309 #else 1310 1310 return DefWindowProcA (hwnd, uMsg, wParam, lParam); 1311 1311 #endif 1312 1312 } … … 1329 1329 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 1330 1330 wndClass.lpszClassName = DATETIMEPICK_CLASSA; 1331 1331 1332 1332 RegisterClassA (&wndClass); 1333 1333 } -
trunk/src/comctl32/flatsb.c
r6705 r6709 39 39 40 40 /*********************************************************************** 41 * 42 * 43 * 41 * InitializeFlatSB 42 * 43 * returns nonzero if successful, zero otherwise 44 44 * 45 45 */ … … 52 52 53 53 /*********************************************************************** 54 * 55 * 56 * 57 * E_FAILif one of the scroll bars is currently in use58 * S_FALSEif InitializeFlatSB was never called on this hwnd59 * S_OKotherwise54 * UninitializeFlatSB 55 * 56 * returns: 57 * E_FAIL if one of the scroll bars is currently in use 58 * S_FALSE if InitializeFlatSB was never called on this hwnd 59 * S_OK otherwise 60 60 * 61 61 */ … … 68 68 69 69 /*********************************************************************** 70 * 71 * 72 * 73 * 74 * zero otherwise.75 * 76 */ 77 BOOL WINAPI 70 * FlatSB_GetScrollProp 71 * 72 * Returns nonzero if successful, or zero otherwise. If index is WSB_PROP_HSTYLE, 73 * the return is nonzero if InitializeFlatSB has been called for this window, or 74 * zero otherwise. 75 * 76 */ 77 BOOL WINAPI 78 78 FlatSB_GetScrollProp(HWND hwnd, INT propIndex, LPINT prop) 79 79 { … … 84 84 85 85 /*********************************************************************** 86 * 87 */ 88 BOOL WINAPI 86 * FlatSB_SetScrollProp 87 */ 88 BOOL WINAPI 89 89 FlatSB_SetScrollProp(HWND hwnd, UINT index, INT newValue, BOOL flag) 90 90 { … … 95 95 96 96 /*********************************************************************** 97 * 98 * 99 * 100 * 101 * 102 * 103 * 104 * the flat scroll bar functions, flat scroll bars will show up and105 * 106 * 107 * 108 * 109 * 110 */ 111 112 /*********************************************************************** 113 * 114 */ 115 BOOL WINAPI 97 * From the Microsoft docs: 98 * "If flat scroll bars haven't been initialized for the 99 * window, the flat scroll bar APIs will defer to the corresponding 100 * standard APIs. This allows the developer to turn flat scroll 101 * bars on and off without having to write conditional code." 102 * 103 * So, if we just call the standard functions until we implement 104 * the flat scroll bar functions, flat scroll bars will show up and 105 * behave properly, as though they had simply not been setup to 106 * have flat properties. 107 * 108 * Susan <sfarley@codeweavers.com> 109 * 110 */ 111 112 /*********************************************************************** 113 * FlatSB_EnableScrollBar 114 */ 115 BOOL WINAPI 116 116 FlatSB_EnableScrollBar(HWND hwnd, int nBar, UINT flags) 117 117 { … … 120 120 121 121 /*********************************************************************** 122 * 123 */ 124 BOOL WINAPI 122 * FlatSB_ShowScrollBar 123 */ 124 BOOL WINAPI 125 125 FlatSB_ShowScrollBar(HWND hwnd, int nBar, BOOL fShow) 126 126 { … … 129 129 130 130 /*********************************************************************** 131 * 132 */ 133 BOOL WINAPI 131 * FlatSB_GetScrollRange 132 */ 133 BOOL WINAPI 134 134 FlatSB_GetScrollRange(HWND hwnd, int nBar, LPINT min, LPINT max) 135 135 { … … 138 138 139 139 /*********************************************************************** 140 * 141 */ 142 BOOL WINAPI 140 * FlatSB_GetScrollInfo 141 */ 142 BOOL WINAPI 143 143 FlatSB_GetScrollInfo(HWND hwnd, int nBar, LPSCROLLINFO info) 144 144 { … … 147 147 148 148 /*********************************************************************** 149 * 150 */ 151 INT WINAPI 149 * FlatSB_GetScrollPos 150 */ 151 INT WINAPI 152 152 FlatSB_GetScrollPos(HWND hwnd, int nBar) 153 153 { … … 156 156 157 157 /*********************************************************************** 158 * 159 */ 160 INT WINAPI 158 * FlatSB_SetScrollPos 159 */ 160 INT WINAPI 161 161 FlatSB_SetScrollPos(HWND hwnd, int nBar, INT pos, BOOL bRedraw) 162 162 { … … 165 165 166 166 /*********************************************************************** 167 * 168 */ 169 INT WINAPI 167 * FlatSB_SetScrollInfo 168 */ 169 INT WINAPI 170 170 FlatSB_SetScrollInfo(HWND hwnd, int nBar, LPSCROLLINFO info, BOOL bRedraw) 171 171 { … … 174 174 175 175 /*********************************************************************** 176 * 177 */ 178 INT WINAPI 176 * FlatSB_SetScrollRange 177 */ 178 INT WINAPI 179 179 FlatSB_SetScrollRange(HWND hwnd, int nBar, INT min, INT max, BOOL bRedraw) 180 180 { … … 212 212 switch (uMsg) 213 213 { 214 215 216 217 218 219 220 221 222 214 case WM_CREATE: 215 return FlatSB_Create (hwnd, wParam, lParam); 216 217 case WM_DESTROY: 218 return FlatSB_Destroy (hwnd, wParam, lParam); 219 220 default: 221 if (uMsg >= WM_USER) 222 ERR("unknown msg %04x wp=%08x lp=%08lx\n", 223 223 uMsg, wParam, lParam); 224 224 #ifdef __WIN32OS2__ 225 225 return defComCtl32ProcA (hwnd, uMsg, wParam, lParam); 226 226 #else 227 227 return DefWindowProcA (hwnd, uMsg, wParam, lParam); 228 228 #endif 229 229 } … … 245 245 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 246 246 wndClass.lpszClassName = FLATSB_CLASSA; 247 247 248 248 RegisterClassA (&wndClass); 249 249 } -
trunk/src/comctl32/imagelist.c
r6705 r6709 20 20 * - ImageList_Draw, ImageList_DrawEx and ImageList_GetIcon use 21 21 * ImageList_DrawIndirect. Since ImageList_DrawIndirect is still 22 * partially implemented, the functions mentioned above will be 22 * partially implemented, the functions mentioned above will be 23 23 * limited in functionality too. 24 24 */ … … 69 69 70 70 /************************************************************************* 71 * IMAGELIST_InternalExpandBitmaps [Internal] 71 * IMAGELIST_InternalExpandBitmaps [Internal] 72 72 * 73 73 * Expands the bitmaps of an image list by the given number of images. … … 92 92 if ((himl->cCurImage + nImageCount < himl->cMaxImage) 93 93 && (himl->cy >= cy)) 94 94 return; 95 95 96 96 if (cy == 0) cy = himl->cy; … … 116 116 117 117 if (himl->hbmMask) { 118 hbmNewBitmap = 118 hbmNewBitmap = 119 119 CreateBitmap (nNewWidth, cy, 1, 1, NULL); 120 120 … … 138 138 139 139 /************************************************************************* 140 * IMAGELIST_InternalDraw [Internal] 140 * IMAGELIST_InternalDraw [Internal] 141 141 * 142 142 * Draws the image in the ImageList (without the mask) … … 151 151 * 152 152 * NOTES 153 * This function is used by ImageList_DrawIndirect, when it is 153 * This function is used by ImageList_DrawIndirect, when it is 154 154 * required to draw only the Image (without the mask) to the screen. 155 155 * … … 164 164 hImageDC = CreateCompatibleDC(0); 165 165 hOldBitmap = SelectObject(hImageDC, pimldp->himl->hbmImage); 166 BitBlt(pimldp->hdcDst, 166 BitBlt(pimldp->hdcDst, 167 167 pimldp->x, pimldp->y, cx, cy, 168 hImageDC, 169 pimldp->himl->cx * pimldp->i, 0, 168 hImageDC, 169 pimldp->himl->cx * pimldp->i, 0, 170 170 SRCCOPY); 171 171 … … 176 176 177 177 /************************************************************************* 178 * IMAGELIST_InternalDrawMask [Internal] 178 * IMAGELIST_InternalDrawMask [Internal] 179 179 * 180 180 * Draws the image in the ImageList with the mask … … 189 189 * 190 190 * NOTES 191 * This function is used by ImageList_DrawIndirect, when it is 191 * This function is used by ImageList_DrawIndirect, when it is 192 192 * required to draw the Image with the mask to the screen. 193 193 * … … 205 205 UINT fStyle = pimldp->fStyle & (~ILD_OVERLAYMASK); 206 206 207 /* 208 * We need a dc and bitmap to draw on that is 207 /* 208 * We need a dc and bitmap to draw on that is 209 209 * not on the screen. 210 210 */ … … 221 221 hOffScreenDC = CreateCompatibleDC( pimldp->hdcDst ); 222 222 223 if ( hOffScreenDC ) 223 if ( hOffScreenDC ) 224 224 { 225 225 hOffScreenBmp = CreateCompatibleBitmap( pimldp->hdcDst, cx, cy ); 226 226 227 if ( hOffScreenBmp ) 227 if ( hOffScreenBmp ) 228 228 SelectObject( hOffScreenDC, hOffScreenBmp ); 229 229 else … … 235 235 hOldBitmapImage = SelectObject(hImageDC, himlLocal->hbmImage); 236 236 hOldBitmapMask = SelectObject(hMaskDC, himlLocal->hbmMask); 237 238 /* 239 * Get a copy of the image for the masking operations. 237 238 /* 239 * Get a copy of the image for the masking operations. 240 240 * We will use the copy, and this dc for all the various 241 241 * blitting, and then do one final blit to the screen dc. 242 242 * This should clean up most of the flickering. 243 243 */ 244 BitBlt( hOffScreenDC, 0, 0, cx, cy, pimldp->hdcDst, pimldp->x, 244 BitBlt( hOffScreenDC, 0, 0, cx, cy, pimldp->hdcDst, pimldp->x, 245 245 pimldp->y, SRCCOPY); 246 246 247 /* 247 /* 248 248 * Draw the Background for the appropriate Styles 249 249 */ 250 if( bUseCustomBackground && (fStyle == ILD_NORMAL || fStyle & ILD_IMAGE 250 if( bUseCustomBackground && (fStyle == ILD_NORMAL || fStyle & ILD_IMAGE 251 251 || bBlendFlag) ) 252 252 { 253 253 254 254 hBrush = CreateSolidBrush (himlLocal->clrBk); 255 255 hOldBrush = SelectObject (pimldp->hdcDst, hBrush); 256 256 257 257 PatBlt( hOffScreenDC, pimldp->x, pimldp->y, cx, cy, PATCOPY ); 258 258 … … 260 260 } 261 261 262 /* 262 /* 263 263 * Draw Image Transparently over the current background 264 264 */ 265 if(fStyle == ILD_NORMAL || (fStyle & ILD_TRANSPARENT) || 266 ((fStyle & ILD_IMAGE) && bUseCustomBackground) || bBlendFlag) 267 { /* 265 if(fStyle == ILD_NORMAL || (fStyle & ILD_TRANSPARENT) || 266 ((fStyle & ILD_IMAGE) && bUseCustomBackground) || bBlendFlag) 267 { /* 268 268 * To obtain a transparent look, background color should be set 269 * to white and foreground color to black when blting the 270 * monochrome mask. 269 * to white and foreground color to black when blting the 270 * monochrome mask. 271 271 */ 272 273 oldBkColor = SetBkColor( hOffScreenDC, RGB( 0xff, 0xff, 0xff ) ); 272 273 oldBkColor = SetBkColor( hOffScreenDC, RGB( 0xff, 0xff, 0xff ) ); 274 274 oldFgColor = SetTextColor( hOffScreenDC, RGB( 0, 0, 0 ) ); 275 275 … … 279 279 BitBlt( hOffScreenDC, 0, 0, cx, cy, hImageDC,himlLocal->cx * pimldp->i, 280 280 0, SRCPAINT ); 281 282 } 283 281 282 } 283 284 284 /* 285 285 * Draw the image when no Background is specified … … 287 287 else if((fStyle & ILD_IMAGE) && !bUseCustomBackground) 288 288 { 289 BitBlt( hOffScreenDC, 0, 0, cx, cy, hImageDC, 289 BitBlt( hOffScreenDC, 0, 0, cx, cy, hImageDC, 290 290 himlLocal->cx * pimldp->i, 0, SRCCOPY); 291 291 } 292 /* 292 /* 293 293 * Draw the mask with or without a background 294 294 */ … … 298 298 0, bUseCustomBackground ? SRCCOPY : SRCAND); 299 299 } 300 300 301 301 /* 302 302 * Blit the bitmap to the screen now. … … 305 305 hOffScreenDC, 0, 0, SRCCOPY); 306 306 307 307 308 308 SelectObject(hImageDC, hOldBitmapImage); 309 309 SelectObject(hMaskDC, hOldBitmapMask); 310 310 311 311 cleanup: 312 312 313 313 DeleteDC(hImageDC); 314 314 DeleteDC(hMaskDC); 315 315 316 316 DeleteDC( hOffScreenDC ); 317 317 DeleteObject( hOffScreenBmp ); 318 318 319 319 return; 320 320 } 321 321 322 322 /************************************************************************* 323 * IMAGELIST_InternalDrawBlend [Internal] 324 * 325 * Draws the Blend over the current image 323 * IMAGELIST_InternalDrawBlend [Internal] 324 * 325 * Draws the Blend over the current image 326 326 * 327 327 * PARAMS … … 334 334 * 335 335 * NOTES 336 * This functions is used by ImageList_DrawIndirect, when it is 337 * required to add the blend to the current image. 338 * 336 * This functions is used by ImageList_DrawIndirect, when it is 337 * required to add the blend to the current image. 338 * 339 339 */ 340 340 static VOID … … 375 375 376 376 BitBlt(hBlendMaskDC, 377 0,0, cx, cy, 377 0,0, cx, cy, 378 378 hMaskDC, 379 379 himlLocal->cx * pimldp->i,0, … … 381 381 382 382 BitBlt(hBlendMaskDC, 383 0,0, cx, cy, 383 0,0, cx, cy, 384 384 hBlendMaskDC, 385 0,0, 385 0,0, 386 386 NOTSRCCOPY); 387 387 … … 397 397 hOldBrush = (HBRUSH) SelectObject (pimldp->hdcDst, hBlendColorBrush); 398 398 399 BitBlt (pimldp->hdcDst, 400 pimldp->x, pimldp->y, cx, cy, 401 hBlendMaskDC, 402 0, 0, 399 BitBlt (pimldp->hdcDst, 400 pimldp->x, pimldp->y, cx, cy, 401 hBlendMaskDC, 402 0, 0, 403 403 0xB8074A); /* PSDPxax */ 404 404 … … 413 413 414 414 /************************************************************************* 415 * IMAGELIST_InternalDrawOverlay [Internal] 416 * 417 * Draws the overlay image 415 * IMAGELIST_InternalDrawOverlay [Internal] 416 * 417 * Draws the overlay image 418 418 * 419 419 * PARAMS … … 426 426 * 427 427 * NOTES 428 * This functions is used by ImageList_DrawIndirect, when it is 428 * This functions is used by ImageList_DrawIndirect, when it is 429 429 * required to draw the overlay 430 430 * 431 * 432 */ 433 static VOID 431 * 432 */ 433 static VOID 434 434 IMAGELIST_InternalDrawOverlay(IMAGELISTDRAWPARAMS *pimldp, INT cx, INT cy) 435 435 { … … 447 447 if (pimldp->himl->hbmMask) 448 448 { 449 hOldBitmap = (HBITMAP) SelectObject (hImageDC, 449 hOldBitmap = (HBITMAP) SelectObject (hImageDC, 450 450 pimldp->himl->hbmMask); 451 451 452 BitBlt (pimldp->hdcDst, 452 BitBlt (pimldp->hdcDst, 453 453 pimldp->x, pimldp->y, cx, cy, 454 454 hImageDC, pimldp->himl->cx * nOvlIdx, 0, … … 457 457 SelectObject(hImageDC, hOldBitmap); 458 458 } 459 hOldBitmap = (HBITMAP) SelectObject (hImageDC, 459 hOldBitmap = (HBITMAP) SelectObject (hImageDC, 460 460 pimldp->himl->hbmImage); 461 461 462 BitBlt (pimldp->hdcDst, 463 pimldp->x, pimldp->y, cx, cy, 462 BitBlt (pimldp->hdcDst, 463 pimldp->x, pimldp->y, cx, cy, 464 464 hImageDC, 465 465 pimldp->himl->cx * nOvlIdx, 0, … … 492 492 493 493 INT WINAPI 494 ImageList_Add (HIMAGELIST himl, 494 ImageList_Add (HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask) 495 495 { 496 496 HDC hdcImage, hdcBitmap; … … 531 531 hOldBitmapTemp = (HBITMAP) SelectObject(hdcTemp, hbmMask); 532 532 533 BitBlt (hdcMask, 533 BitBlt (hdcMask, 534 534 nStartX, 0, bmp.bmWidth, bmp.bmHeight, 535 hdcTemp, 536 0, 0, 535 hdcTemp, 536 0, 0, 537 537 SRCCOPY); 538 538 … … 542 542 /* Remove the background from the image 543 543 */ 544 BitBlt (hdcImage, 544 BitBlt (hdcImage, 545 545 nStartX, 0, bmp.bmWidth, bmp.bmHeight, 546 hdcMask, 547 nStartX, 0, 546 hdcMask, 547 nStartX, 0, 548 548 0x220326); /* NOTSRCAND */ 549 549 … … 586 586 587 587 /************************************************************************* 588 * ImageList_AddMasked [COMCTL32.42] 588 * ImageList_AddMasked [COMCTL32.42] 589 589 * 590 590 * Adds an image or images to an image list and creates a mask from the … … 651 651 GetPixel (hdcBitmap, 0, 0); 652 652 SetBkColor (hdcBitmap, bkColor); 653 BitBlt (hdcMask, 653 BitBlt (hdcMask, 654 654 nMaskXOffset, 0, bmp.bmWidth, bmp.bmHeight, 655 hdcBitmap, 0, 0, 655 hdcBitmap, 0, 0, 656 656 SRCCOPY); 657 657 … … 668 668 This is here in case some apps rely on this bug 669 669 */ 670 BitBlt(hdcBitmap, 670 BitBlt(hdcBitmap, 671 671 0, 0, bmp.bmWidth, bmp.bmHeight, 672 hdcMask, 673 nMaskXOffset, 0, 672 hdcMask, 673 nMaskXOffset, 0, 674 674 0x220326); /* NOTSRCAND */ 675 675 /* Copy result to the imagelist 676 676 */ 677 BitBlt (hdcImage, 677 BitBlt (hdcImage, 678 678 nIndex * himl->cx, 0, bmp.bmWidth, bmp.bmHeight, 679 hdcBitmap, 680 0, 0, 679 hdcBitmap, 680 0, 0, 681 681 SRCCOPY); 682 682 /* Clean up … … 698 698 699 699 /************************************************************************* 700 * ImageList_BeginDrag [COMCTL32.43] 700 * ImageList_BeginDrag [COMCTL32.43] 701 701 * 702 702 * Creates a temporary image list that contains one image. It will be used … … 716 716 BOOL WINAPI 717 717 ImageList_BeginDrag (HIMAGELIST himlTrack, INT iTrack, 718 718 INT dxHotspot, INT dyHotspot) 719 719 { 720 720 HDC hdcSrc, hdcDst; … … 723 723 724 724 if (himlTrack == NULL) 725 725 return FALSE; 726 726 727 727 if (himlInternalDrag) … … 729 729 730 730 himlInternalDrag = 731 732 731 ImageList_Create (himlTrack->cx, himlTrack->cy, 732 himlTrack->flags, 1, 1); 733 733 if (himlInternalDrag == NULL) { 734 734 ERR("Error creating drag image list!\n"); … … 764 764 765 765 /************************************************************************* 766 * ImageList_Copy [COMCTL32.44] 767 * 768 * Copies an image of the source image list to an image of the 766 * ImageList_Copy [COMCTL32.44] 767 * 768 * Copies an image of the source image list to an image of the 769 769 * destination image list. Images can be copied or swapped. 770 770 * … … 787 787 788 788 BOOL WINAPI 789 ImageList_Copy (HIMAGELIST himlDst, INT iDst, 790 791 { 792 HDC hdcSrc, hdcDst; 789 ImageList_Copy (HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc, 790 INT iSrc, INT uFlags) 791 { 792 HDC hdcSrc, hdcDst; 793 793 794 794 TRACE("iDst=%d iSrc=%d\n", iDst, iSrc); 795 795 796 796 if ((himlSrc == NULL) || (himlDst == NULL)) 797 797 return FALSE; 798 798 if ((iDst < 0) || (iDst >= himlDst->cCurImage)) 799 799 return FALSE; 800 800 if ((iSrc < 0) || (iSrc >= himlSrc->cCurImage)) 801 801 return FALSE; 802 802 803 803 hdcSrc = CreateCompatibleDC (0); … … 815 815 himlSrc->uBitsPixel, NULL); 816 816 hbmTempMask = CreateBitmap (himlSrc->cx, himlSrc->cy, 1, 817 817 1, NULL); 818 818 819 819 /* copy (and stretch) destination to temporary bitmaps.(save) */ … … 908 908 HIMAGELIST WINAPI 909 909 ImageList_Create (INT cx, INT cy, UINT flags, 910 910 INT cInitial, INT cGrow) 911 911 { 912 912 HIMAGELIST himl; … … 914 914 INT nCount; 915 915 HBITMAP hbmTemp; 916 static WORD aBitBlend25[] = 916 static WORD aBitBlend25[] = 917 917 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00}; 918 918 … … 948 948 if (himl->cMaxImage > 0) { 949 949 himl->hbmImage = 950 950 CreateBitmap (himl->cx * himl->cMaxImage, himl->cy, 951 951 1, himl->uBitsPixel, NULL); 952 953 954 955 952 if (himl->hbmImage == 0) { 953 ERR("Error creating image bitmap!\n"); 954 return NULL; 955 } 956 956 } 957 957 else 958 958 himl->hbmImage = 0; 959 959 960 960 if ( (himl->cMaxImage > 0) && (himl->flags & ILC_MASK)) { 961 961 himl->hbmMask = CreateBitmap (himl->cx * himl->cMaxImage, himl->cy, 962 962 1, 1, NULL); 963 963 if (himl->hbmMask == 0) { 964 964 ERR("Error creating mask bitmap!\n"); … … 986 986 987 987 /************************************************************************* 988 * ImageList_Destroy [COMCTL32.46] 988 * ImageList_Destroy [COMCTL32.46] 989 989 * 990 990 * Destroys an image list. … … 1000 1000 BOOL WINAPI 1001 1001 ImageList_Destroy (HIMAGELIST himl) 1002 { 1002 { 1003 1003 if (!himl) 1004 1004 return FALSE; 1005 1005 1006 1006 /* delete image bitmaps */ … … 1015 1015 if (himl->hbrBlend50) 1016 1016 DeleteObject (himl->hbrBlend50); 1017 1017 1018 1018 COMCTL32_Free (himl); 1019 1019 … … 1023 1023 1024 1024 /************************************************************************* 1025 * ImageList_DragEnter [COMCTL32.47] 1025 * ImageList_DragEnter [COMCTL32.47] 1026 1026 * 1027 1027 * Locks window update and displays the drag image at the given position. … … 1045 1045 { 1046 1046 if (himlInternalDrag == NULL) 1047 1047 return FALSE; 1048 1048 1049 1049 if (hwndLock) 1050 1050 hwndInternalDrag = hwndLock; 1051 1051 else 1052 1052 hwndInternalDrag = GetDesktopWindow (); 1053 1053 1054 1054 xInternalPos = x; … … 1057 1057 hdcBackBuffer = CreateCompatibleDC (0); 1058 1058 hbmBackBuffer = CreateCompatibleBitmap (hdcBackBuffer, 1059 1059 himlInternalDrag->cx, himlInternalDrag->cy); 1060 1060 1061 1061 ImageList_DragShowNolock (TRUE); … … 1066 1066 1067 1067 /************************************************************************* 1068 * ImageList_DragLeave [COMCTL32.48] 1068 * ImageList_DragLeave [COMCTL32.48] 1069 1069 * 1070 1070 * Unlocks window update and hides the drag image. … … 1082 1082 { 1083 1083 if (hwndLock) 1084 1084 hwndInternalDrag = hwndLock; 1085 1085 else 1086 1086 hwndInternalDrag = GetDesktopWindow (); 1087 1087 1088 1088 ImageList_DragShowNolock (FALSE); … … 1096 1096 1097 1097 /************************************************************************* 1098 * ImageList_DragMove [COMCTL32.49] 1098 * ImageList_DragMove [COMCTL32.49] 1099 1099 * 1100 1100 * Moves the drag image. … … 1128 1128 1129 1129 /************************************************************************* 1130 * ImageList_DragShowNolock [COMCTL32.50] 1130 * ImageList_DragShowNolock [COMCTL32.50] 1131 1131 * 1132 1132 * Shows or hides the drag image. … … 1152 1152 1153 1153 hdcDrag = GetDCEx (hwndInternalDrag, 0, 1154 1154 DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE); 1155 1155 1156 1156 if (bShow) { 1157 1158 1159 1160 1161 1157 /* show drag image */ 1158 1159 /* save background */ 1160 1161 /* draw drag image */ 1162 1162 1163 1163 } 1164 1164 else { 1165 1166 1167 1165 /* hide drag image */ 1166 1167 /* restore background */ 1168 1168 1169 1169 } … … 1199 1199 BOOL WINAPI 1200 1200 ImageList_Draw (HIMAGELIST himl, INT i, HDC hdc, 1201 1201 INT x, INT y, UINT fStyle) 1202 1202 { 1203 1203 IMAGELISTDRAWPARAMS imldp; … … 1252 1252 BOOL WINAPI 1253 1253 ImageList_DrawEx (HIMAGELIST himl, INT i, HDC hdc, INT x, INT y, 1254 1255 1254 INT dx, INT dy, COLORREF rgbBk, COLORREF rgbFg, 1255 UINT fStyle) 1256 1256 { 1257 1257 IMAGELISTDRAWPARAMS imldp; … … 1277 1277 1278 1278 /************************************************************************* 1279 * ImageList_DrawIndirect [COMCTL32.53] 1279 * ImageList_DrawIndirect [COMCTL32.53] 1280 1280 * 1281 1281 * Draws an image using ... … … 1292 1292 ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp) 1293 1293 { 1294 INT cx, cy; 1295 /* 1294 INT cx, cy; 1295 /* 1296 1296 Do some Error Checking 1297 1297 */ … … 1303 1303 return FALSE; 1304 1304 if ((pimldp->i < 0) || (pimldp->i >= pimldp->himl->cCurImage)) { 1305 1305 ERR("%d not within range (max %d)\n",pimldp->i,pimldp->himl->cCurImage-1); 1306 1306 return FALSE; 1307 1307 } … … 1322 1322 IMAGELIST_InternalDraw(pimldp, cx, cy); 1323 1323 } 1324 /* 1324 /* 1325 1325 Apply the blend if needed to the Image 1326 1326 */ … … 1387 1387 DeleteDC (hdcSrc); 1388 1388 1389 1390 1389 himlDst->cCurImage = himlSrc->cCurImage; 1390 himlDst->cMaxImage = himlSrc->cMaxImage; 1391 1391 } 1392 1392 return himlDst; … … 1447 1447 { 1448 1448 if (himl == NULL) 1449 1449 return CLR_NONE; 1450 1450 1451 1451 return himl->clrBk; … … 1483 1483 1484 1484 /************************************************************************* 1485 * ImageList_GetIcon [COMCTL32.59] 1485 * ImageList_GetIcon [COMCTL32.59] 1486 1486 * 1487 1487 * Creates an icon from a masked image of an image list. … … 1506 1506 1507 1507 if ((himl == NULL) || (i < 0) || (i >= himl->cCurImage)) { 1508 1509 1508 FIXME("(%p,%d,%x), params out of range!\n",himl,i,fStyle); 1509 return 0; 1510 1510 } 1511 1511 … … 1519 1519 hOldDstBitmap = (HBITMAP)SelectObject (hdcDst, ii.hbmMask); 1520 1520 if (himl->hbmMask) { 1521 1522 1523 1521 SelectObject (hdcSrc, himl->hbmMask); 1522 BitBlt (hdcDst, 0, 0, himl->cx, himl->cy, 1523 hdcSrc, i * himl->cx, 0, SRCCOPY); 1524 1524 } 1525 1525 else 1526 1526 PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, BLACKNESS); 1527 1527 1528 1528 /* draw image*/ … … 1531 1531 SelectObject (hdcDst, ii.hbmColor); 1532 1532 BitBlt (hdcDst, 0, 0, himl->cx, himl->cy, 1533 1533 hdcSrc, i * himl->cx, 0, SRCCOPY); 1534 1534 1535 1535 /* 1536 1536 * CreateIconIndirect requires us to deselect the bitmaps from 1537 * the DCs before calling 1537 * the DCs before calling 1538 1538 */ 1539 1539 SelectObject(hdcSrc, hOldSrcBitmap); 1540 1540 SelectObject(hdcDst, hOldDstBitmap); 1541 1541 1542 hIcon = CreateIconIndirect (&ii); 1542 hIcon = CreateIconIndirect (&ii); 1543 1543 1544 1544 DeleteDC (hdcSrc); … … 1573 1573 { 1574 1574 if (himl == NULL) 1575 1575 return FALSE; 1576 1576 if ((himl->cx <= 0) || (himl->cy <= 0)) 1577 1577 return FALSE; 1578 1578 1579 1579 if (cx) 1580 1580 *cx = himl->cx; 1581 1581 if (cy) 1582 1582 *cy = himl->cy; 1583 1583 1584 1584 return TRUE; … … 1603 1603 { 1604 1604 if (himl == NULL) 1605 1605 return 0; 1606 1606 1607 1607 return himl->cCurImage; … … 1628 1628 { 1629 1629 if ((himl == NULL) || (pImageInfo == NULL)) 1630 1630 return FALSE; 1631 1631 if ((i < 0) || (i >= himl->cCurImage)) 1632 1632 return FALSE; 1633 1633 1634 1634 pImageInfo->hbmImage = himl->hbmImage; 1635 1635 pImageInfo->hbmMask = himl->hbmMask; 1636 1636 1637 1637 pImageInfo->rcImage.top = 0; 1638 1638 pImageInfo->rcImage.bottom = himl->cy; 1639 1639 pImageInfo->rcImage.left = i * himl->cx; 1640 1640 pImageInfo->rcImage.right = (i+1) * himl->cx; 1641 1641 1642 1642 return TRUE; 1643 1643 } … … 1645 1645 1646 1646 /************************************************************************* 1647 * ImageList_GetImageRect [COMCTL32.63] 1647 * ImageList_GetImageRect [COMCTL32.63] 1648 1648 * 1649 1649 * Retrieves the rectangle of the specified image in an image list. … … 1666 1666 { 1667 1667 if ((himl == NULL) || (lpRect == NULL)) 1668 1668 return FALSE; 1669 1669 if ((i < 0) || (i >= himl->cCurImage)) 1670 1670 return FALSE; 1671 1671 1672 1672 lpRect->left = i * himl->cx; … … 1704 1704 HIMAGELIST WINAPI 1705 1705 ImageList_LoadImageA (HINSTANCE hi, LPCSTR lpbmp, INT cx, INT cGrow, 1706 1706 COLORREF clrMask, UINT uType, UINT uFlags) 1707 1707 { 1708 1708 HIMAGELIST himl = NULL; … … 1744 1744 GetIconInfo (handle, &ii); 1745 1745 GetObjectA (ii.hbmColor, sizeof(BITMAP), (LPVOID)&bmp); 1746 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight, 1746 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight, 1747 1747 ILC_MASK | ILC_COLOR, 1, cGrow); 1748 1748 ImageList_Add (himl, ii.hbmColor, ii.hbmMask); … … 1752 1752 1753 1753 DeleteObject (handle); 1754 1754 1755 1755 return himl; 1756 1756 } … … 1781 1781 HIMAGELIST WINAPI 1782 1782 ImageList_LoadImageW (HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow, 1783 COLORREF clrMask, UINT uType,UINT uFlags)1783 COLORREF clrMask, UINT uType, UINT uFlags) 1784 1784 { 1785 1785 HIMAGELIST himl = NULL; … … 1808 1808 GetIconInfo (handle, &ii); 1809 1809 GetObjectA (ii.hbmMask, sizeof(BITMAP), (LPVOID)&bmp); 1810 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight, 1810 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight, 1811 1811 ILC_MASK | ILC_COLOR, 1, cGrow); 1812 1812 ImageList_Add (himl, ii.hbmColor, ii.hbmMask); … … 1816 1816 1817 1817 DeleteObject (handle); 1818 1818 1819 1819 return himl; 1820 1820 } … … 1822 1822 1823 1823 /************************************************************************* 1824 * ImageList_Merge [COMCTL32.67] 1824 * ImageList_Merge [COMCTL32.67] 1825 1825 * 1826 1826 * Creates a new image list that contains a merged image from the specified … … 1842 1842 HIMAGELIST WINAPI 1843 1843 ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2, 1844 1844 INT dx, INT dy) 1845 1845 { 1846 1846 HIMAGELIST himlDst = NULL; … … 1851 1851 1852 1852 if ((himl1 == NULL) || (himl2 == NULL)) 1853 1853 return NULL; 1854 1854 1855 1855 /* check indices */ … … 1903 1903 nX1 = i1 * himl1->cx; 1904 1904 nX2 = i2 * himl2->cx; 1905 1905 1906 1906 /* copy image */ 1907 1907 SelectObject (hdcSrcImage, himl1->hbmImage); 1908 1908 SelectObject (hdcDstImage, himlDst->hbmImage); 1909 BitBlt (hdcDstImage, 0, 0, cxDst, cyDst, 1909 BitBlt (hdcDstImage, 0, 0, cxDst, cyDst, 1910 1910 hdcSrcImage, 0, 0, BLACKNESS); 1911 BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy, 1911 BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy, 1912 1912 hdcSrcImage, nX1, 0, SRCCOPY); 1913 1913 1914 1914 SelectObject (hdcSrcImage, himl2->hbmMask); 1915 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy, 1915 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy, 1916 1916 hdcSrcImage, nX2, 0, SRCAND); 1917 1917 1918 1918 SelectObject (hdcSrcImage, himl2->hbmImage); 1919 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy, 1919 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy, 1920 1920 hdcSrcImage, nX2, 0, SRCPAINT); 1921 1921 … … 1923 1923 SelectObject (hdcSrcImage, himl1->hbmMask); 1924 1924 SelectObject (hdcDstImage, himlDst->hbmMask); 1925 BitBlt (hdcDstImage, 0, 0, cxDst, cyDst, 1925 BitBlt (hdcDstImage, 0, 0, cxDst, cyDst, 1926 1926 hdcSrcImage, 0, 0, WHITENESS); 1927 BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy, 1927 BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy, 1928 1928 hdcSrcImage, nX1, 0, SRCCOPY); 1929 1929 1930 1930 SelectObject (hdcSrcImage, himl2->hbmMask); 1931 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy, 1931 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy, 1932 1932 hdcSrcImage, nX2, 0, SRCAND); 1933 1933 … … 1935 1935 DeleteDC (hdcDstImage); 1936 1936 } 1937 1937 1938 1938 return himlDst; 1939 1939 } … … 1945 1945 int bitspixel = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES); 1946 1946 if (bitspixel>8) 1947 1947 return TRUE; 1948 1948 if (bitspixel<=4) 1949 1949 return FALSE; 1950 1950 return GetDeviceCaps(hdc,CAPS1) & C1_DIBENGINE; 1951 1951 } … … 1954 1954 /* helper for ImageList_Read, see comments below */ 1955 1955 static HBITMAP _read_bitmap(LPSTREAM pstm,int ilcFlag,int cx,int cy) { 1956 HDC 1957 BITMAPFILEHEADER 1958 BITMAPINFOHEADER 1959 int 1960 LPBITMAPINFOHEADER 1961 int 1962 HBITMAP 1963 LPBYTE 1964 int 1965 1966 if (!SUCCEEDED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL)) 1967 (bmfh.bfType != (('M'<<8)|'B'))||1968 !SUCCEEDED(IStream_Read ( pstm, &bmih, sizeof(bmih), NULL))||1969 1956 HDC xdc = 0; 1957 BITMAPFILEHEADER bmfh; 1958 BITMAPINFOHEADER bmih; 1959 int bitsperpixel,palspace,longsperline,width,height; 1960 LPBITMAPINFOHEADER bmihc = NULL; 1961 int result = 0; 1962 HBITMAP hbitmap = 0; 1963 LPBYTE bits = NULL,nbits = NULL; 1964 int nbytesperline,bytesperline; 1965 1966 if (!SUCCEEDED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL)) || 1967 (bmfh.bfType != (('M'<<8)|'B')) || 1968 !SUCCEEDED(IStream_Read ( pstm, &bmih, sizeof(bmih), NULL)) || 1969 (bmih.biSize != sizeof(bmih)) 1970 1970 ) 1971 1971 return 0; 1972 1972 1973 1973 bitsperpixel = bmih.biPlanes * bmih.biBitCount; 1974 1974 if (bitsperpixel<=8) 1975 1975 palspace = (1<<bitsperpixel)*sizeof(RGBQUAD); 1976 1976 else 1977 1977 palspace = 0; 1978 1978 width = bmih.biWidth; 1979 1979 height = bmih.biHeight; 1980 1980 bmihc = (LPBITMAPINFOHEADER)LocalAlloc(LMEM_ZEROINIT,sizeof(bmih)+palspace); 1981 1981 memcpy(bmihc,&bmih,sizeof(bmih)); 1982 longsperline 1983 bmihc->biSizeImage 1982 longsperline = ((width*bitsperpixel+31)&~0x1f)>>5; 1983 bmihc->biSizeImage = (longsperline*height)<<2; 1984 1984 1985 1985 /* read the palette right after the end of the bitmapinfoheader */ 1986 1986 if (palspace) 1987 1988 1987 if (!SUCCEEDED(IStream_Read ( pstm, bmihc+1, palspace, NULL))) 1988 goto ret1; 1989 1989 1990 1990 xdc = GetDC(0); 1991 1991 #if 0 /* Magic for NxM -> 1x(N*M) not implemented for DIB Sections */ 1992 1992 if ((bitsperpixel>1) && 1993 1993 ((ilcFlag!=ILC_COLORDDB) && (!ilcFlag || may_use_dibsection(xdc))) 1994 1994 ) { 1995 1996 1997 1998 1999 2000 1995 hbitmap = CreateDIBSection(xdc,(BITMAPINFO*)bmihc,0,(LPVOID*)&bits,0,0); 1996 if (!hbitmap) 1997 goto ret1; 1998 if (!SUCCEEDED(IStream_Read( pstm, bits, bmihc->biSizeImage, NULL))) 1999 goto ret1; 2000 result = 1; 2001 2001 } else 2002 2002 #endif 2003 2003 { 2004 2005 2006 nwidth= width*(height/cy);2007 nheight= cy;2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 bytesperline= longsperline*4;2023 nbytesperline= (height/cy)*bytesperline;2024 2025 2026 2027 2028 2029 2030 2031 bmihc->biWidth= nwidth;2032 bmihc->biHeight= nheight;2033 2034 2035 2036 2037 2004 int i,nwidth,nheight; 2005 2006 nwidth = width*(height/cy); 2007 nheight = cy; 2008 2009 if (bitsperpixel==1) 2010 hbitmap = CreateBitmap(nwidth,nheight,1,1,NULL); 2011 else 2012 hbitmap = CreateCompatibleBitmap(xdc,nwidth,nheight); 2013 2014 /* Might be a bit excessive memory use here */ 2015 bits = (LPBYTE)LocalAlloc(LMEM_ZEROINIT,bmihc->biSizeImage); 2016 nbits = (LPBYTE)LocalAlloc(LMEM_ZEROINIT,bmihc->biSizeImage); 2017 if (!SUCCEEDED(IStream_Read ( pstm, bits, bmihc->biSizeImage, NULL))) 2018 goto ret1; 2019 2020 /* Copy the NxM bitmap into a 1x(N*M) bitmap we need, linewise */ 2021 /* Do not forget that windows bitmaps are bottom->top */ 2022 bytesperline = longsperline*4; 2023 nbytesperline = (height/cy)*bytesperline; 2024 for (i=0;i<height;i++) { 2025 memcpy( 2026 nbits+((height-1-i)%cy)*nbytesperline+(i/cy)*bytesperline, 2027 bits+bytesperline*(height-1-i), 2028 bytesperline 2029 ); 2030 } 2031 bmihc->biWidth = nwidth; 2032 bmihc->biHeight = nheight; 2033 if (!SetDIBits(xdc,hbitmap,0,nheight,nbits,(BITMAPINFO*)bmihc,0)) 2034 goto ret1; 2035 LocalFree((HLOCAL)nbits); 2036 LocalFree((HLOCAL)bits); 2037 result = 1; 2038 2038 } 2039 2039 ret1: 2040 if (xdc) 2041 if (bmihc) 2040 if (xdc) ReleaseDC(0,xdc); 2041 if (bmihc) LocalFree((HLOCAL)bmihc); 2042 2042 if (!result) { 2043 2044 2045 2046 2043 if (hbitmap) { 2044 DeleteObject(hbitmap); 2045 hbitmap = 0; 2046 } 2047 2047 } 2048 2048 return hbitmap; … … 2062 2062 * 2063 2063 * The format is like this: 2064 * ILHEADilheadstruct;2064 * ILHEAD ilheadstruct; 2065 2065 * 2066 2066 * for the color image part: 2067 * BITMAPFILEHEADER bmfh;2068 * BITMAPINFOHEADERbmih;2067 * BITMAPFILEHEADER bmfh; 2068 * BITMAPINFOHEADER bmih; 2069 2069 * only if it has a palette: 2070 * RGBQUAD rgbs[nr_of_paletted_colors];2071 * 2072 * BYTEcolorbits[imagesize];2070 * RGBQUAD rgbs[nr_of_paletted_colors]; 2071 * 2072 * BYTE colorbits[imagesize]; 2073 2073 * 2074 2074 * the following only if the ILC_MASK bit is set in ILHEAD.ilFlags: 2075 * BITMAPFILEHEADERbmfh_mask;2076 * BITMAPINFOHEADERbmih_mask;2075 * BITMAPFILEHEADER bmfh_mask; 2076 * BITMAPINFOHEADER bmih_mask; 2077 2077 * only if it has a palette (it usually does not): 2078 * RGBQUAD rgbs[nr_of_paletted_colors];2079 * 2080 * BYTEmaskbits[imagesize];2078 * RGBQUAD rgbs[nr_of_paletted_colors]; 2079 * 2080 * BYTE maskbits[imagesize]; 2081 2081 * 2082 2082 * CAVEAT: Those images are within a NxM bitmap, not the 1xN we expect. … … 2085 2085 HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm) 2086 2086 { 2087 ILHEAD 2088 HIMAGELIST 2089 HBITMAP 2090 int 2087 ILHEAD ilHead; 2088 HIMAGELIST himl; 2089 HBITMAP hbmColor=0,hbmMask=0; 2090 int i; 2091 2091 2092 2092 if (!SUCCEEDED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL))) 2093 2093 return NULL; 2094 2094 if (ilHead.usMagic != (('L' << 8) | 'I')) 2095 2095 return NULL; 2096 2096 if (ilHead.usVersion != 0x101) /* probably version? */ 2097 2097 return NULL; 2098 2098 2099 2099 #if 0 2100 FIXME(" 2101 FIXME(" 2102 FIXME(" 2103 FIXME(" 2104 FIXME(" 2105 FIXME(" 2106 FIXME(" 2107 FIXME(" 2108 FIXME(" 2109 FIXME(" 2100 FIXME(" ilHead.cCurImage = %d\n",ilHead.cCurImage); 2101 FIXME(" ilHead.cMaxImage = %d\n",ilHead.cMaxImage); 2102 FIXME(" ilHead.cGrow = %d\n",ilHead.cGrow); 2103 FIXME(" ilHead.cx = %d\n",ilHead.cx); 2104 FIXME(" ilHead.cy = %d\n",ilHead.cy); 2105 FIXME(" ilHead.flags = %x\n",ilHead.flags); 2106 FIXME(" ilHead.ovls[0] = %d\n",ilHead.ovls[0]); 2107 FIXME(" ilHead.ovls[1] = %d\n",ilHead.ovls[1]); 2108 FIXME(" ilHead.ovls[2] = %d\n",ilHead.ovls[2]); 2109 FIXME(" ilHead.ovls[3] = %d\n",ilHead.ovls[3]); 2110 2110 #endif 2111 2111 2112 2112 hbmColor = _read_bitmap(pstm,ilHead.flags & ~ILC_MASK,ilHead.cx,ilHead.cy); 2113 2113 if (!hbmColor) 2114 2114 return NULL; 2115 2115 if (ilHead.flags & ILC_MASK) { 2116 2117 2118 2119 2120 2116 hbmMask = _read_bitmap(pstm,0,ilHead.cx,ilHead.cy); 2117 if (!hbmMask) { 2118 DeleteObject(hbmColor); 2119 return NULL; 2120 } 2121 2121 } 2122 2122 2123 2123 himl = ImageList_Create ( 2124 2125 2126 2127 1,/* initial */2128 2124 ilHead.cx, 2125 ilHead.cy, 2126 ilHead.flags, 2127 1, /* initial */ 2128 ilHead.cGrow 2129 2129 ); 2130 2130 if (!himl) { 2131 2132 2133 2131 DeleteObject(hbmColor); 2132 DeleteObject(hbmMask); 2133 return NULL; 2134 2134 } 2135 2135 himl->hbmImage = hbmColor; … … 2140 2140 ImageList_SetBkColor(himl,ilHead.bkcolor); 2141 2141 for (i=0;i<4;i++) 2142 2142 ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1); 2143 2143 return himl; 2144 2144 } … … 2168 2168 return FALSE; 2169 2169 } 2170 2170 2171 2171 if ((i < -1) || (i >= himl->cCurImage)) { 2172 2172 ERR("index out of range! %d\n", i); … … 2211 2211 TRACE(" - Max. number of images: %d / %d (Old/New)\n", 2212 2212 himl->cMaxImage, himl->cCurImage + himl->cGrow - 1); 2213 2213 2214 2214 hbmNewImage = 2215 2215 CreateBitmap (cxNew, himl->cy, 1, himl->uBitsPixel, NULL); … … 2226 2226 if (i > 0) { 2227 2227 TRACE("Pre image copy: Copy %d images\n", i); 2228 2228 2229 2229 SelectObject (hdcSrc, himl->hbmImage); 2230 2230 SelectObject (hdcDst, hbmNewImage); … … 2277 2277 2278 2278 /************************************************************************* 2279 * ImageList_Replace [COMCTL32.70] 2279 * ImageList_Replace [COMCTL32.70] 2280 2280 * 2281 2281 * Replaces an image in an image list with a new image. … … 2294 2294 BOOL WINAPI 2295 2295 ImageList_Replace (HIMAGELIST himl, INT i, HBITMAP hbmImage, 2296 2296 HBITMAP hbmMask) 2297 2297 { 2298 2298 HDC hdcImageList, hdcImage; … … 2303 2303 return FALSE; 2304 2304 } 2305 2305 2306 2306 if ((i >= himl->cMaxImage) || (i < 0)) { 2307 2307 ERR("Invalid image index!\n"); … … 2333 2333 */ 2334 2334 SelectObject (hdcImageList, himl->hbmImage); 2335 StretchBlt (hdcImageList, 2335 StretchBlt (hdcImageList, 2336 2336 i*himl->cx, 0, himl->cx, himl->cy, 2337 hdcImage, 2338 0, 0, bmp.bmWidth, bmp.bmHeight, 2337 hdcImage, 2338 0, 0, bmp.bmWidth, bmp.bmHeight, 2339 2339 0x220326); /* NOTSRCAND */ 2340 2340 } … … 2375 2375 2376 2376 if (himl == NULL) 2377 2377 return -1; 2378 2378 if ((i >= himl->cMaxImage) || (i < -1)) 2379 2379 return -1; 2380 2380 2381 2381 hBestFitIcon = CopyImage( 2382 hIcon, IMAGE_ICON, 2383 himl->cx, himl->cy, 2382 hIcon, IMAGE_ICON, 2383 himl->cx, himl->cy, 2384 2384 LR_COPYFROMRESOURCE); 2385 2385 2386 2386 GetIconInfo (hBestFitIcon, &ii); 2387 2387 if (ii.hbmMask == 0) 2388 2388 ERR("no mask!\n"); 2389 2389 if (ii.hbmColor == 0) 2390 2390 ERR("no color!\n"); 2391 2391 GetObjectA (ii.hbmMask, sizeof(BITMAP), (LPVOID)&bmp); 2392 2392 … … 2404 2404 TRACE("hdcImageList=0x%x!\n", hdcImageList); 2405 2405 if (hdcImageList == 0) 2406 2406 ERR("invalid hdcImageList!\n"); 2407 2407 2408 2408 hdcImage = CreateCompatibleDC (0); 2409 2409 TRACE("hdcImage=0x%x!\n", hdcImage); 2410 2410 if (hdcImage == 0) 2411 2411 ERR("invalid hdcImage!\n"); 2412 2412 2413 2413 hbmOldDst = SelectObject (hdcImageList, himl->hbmImage); … … 2429 2429 2430 2430 if(hBestFitIcon) 2431 2431 DestroyIcon(hBestFitIcon); 2432 2432 if (hdcImageList) 2433 2433 DeleteDC (hdcImageList); 2434 2434 if (hdcImage) 2435 2435 DeleteDC (hdcImage); 2436 2436 if (ii.hbmColor) 2437 2437 DeleteObject (ii.hbmColor); 2438 2438 if (ii.hbmMask) 2439 2439 DeleteObject (ii.hbmMask); 2440 2440 2441 2441 return nIndex; … … 2444 2444 2445 2445 /************************************************************************* 2446 * ImageList_SetBkColor [COMCTL32.76] 2446 * ImageList_SetBkColor [COMCTL32.76] 2447 2447 * 2448 2448 * Sets the background color of an image list. … … 2463 2463 2464 2464 if (himl == NULL) 2465 2465 return CLR_NONE; 2466 2466 2467 2467 clrOldBk = himl->clrBk; … … 2492 2492 BOOL WINAPI 2493 2493 ImageList_SetDragCursorImage (HIMAGELIST himlDrag, INT iDrag, 2494 2494 INT dxHotspot, INT dyHotspot) 2495 2495 { 2496 2496 HIMAGELIST himlTemp; … … 2499 2499 2500 2500 if (himlInternalDrag == NULL) 2501 2501 return FALSE; 2502 2502 2503 2503 TRACE(" dxH=%d dyH=%d nX=%d nY=%d\n", 2504 2504 dxHotspot, dyHotspot, nInternalDragHotspotX, nInternalDragHotspotY); 2505 2505 2506 2506 himlTemp = ImageList_Merge (himlInternalDrag, 0, himlDrag, iDrag, 2507 2507 dxHotspot, dyHotspot); 2508 2508 2509 2509 ImageList_Destroy (himlInternalDrag); … … 2518 2518 2519 2519 /************************************************************************* 2520 * ImageList_SetFilter [COMCTL32.78] 2520 * ImageList_SetFilter [COMCTL32.78] 2521 2521 * 2522 2522 * Sets a filter (or does something completely different)!!??? … … 2540 2540 { 2541 2541 FIXME("(%p 0x%x 0x%lx):empty stub!\n", 2542 2542 himl, i, dwFilter); 2543 2543 2544 2544 return FALSE; … … 2567 2567 2568 2568 if (!himl) 2569 2569 return FALSE; 2570 2570 2571 2571 /* remove all images */ … … 2617 2617 2618 2618 if (!himl) 2619 2619 return FALSE; 2620 2620 if (himl->cCurImage >= iImageCount) 2621 2621 return FALSE; 2622 2622 if (himl->cMaxImage > iImageCount) 2623 2623 return TRUE; 2624 2624 2625 2625 nNewCount = iImageCount + himl->cGrow; … … 2636 2636 SelectObject (hdcBitmap, hbmNewBitmap); 2637 2637 2638 2638 /* copy images */ 2639 2639 BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy, 2640 2640 hdcImageList, 0, 0, SRCCOPY); 2641 2641 #if 0 2642 2643 2644 2645 PatBlt (hdcBitmap, nCopyCount * himl->cx, 0, 2646 2642 /* delete 'empty' image space */ 2643 SetBkColor (hdcBitmap, RGB(255, 255, 255)); 2644 SetTextColor (hdcBitmap, RGB(0, 0, 0)); 2645 PatBlt (hdcBitmap, nCopyCount * himl->cx, 0, 2646 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS); 2647 2647 #endif 2648 2649 2648 DeleteObject (himl->hbmImage); 2649 himl->hbmImage = hbmNewBitmap; 2650 2650 } 2651 2651 else 2652 2652 ERR("Could not create new image bitmap !\n"); 2653 2653 2654 2654 if (himl->hbmMask) … … 2661 2661 SelectObject (hdcBitmap, hbmNewBitmap); 2662 2662 2663 2663 /* copy images */ 2664 2664 BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy, 2665 2665 hdcImageList, 0, 0, SRCCOPY); 2666 2666 #if 0 2667 2668 2669 2670 PatBlt (hdcBitmap, nCopyCount * himl->cx, 0, 2671 2667 /* delete 'empty' image space */ 2668 SetBkColor (hdcBitmap, RGB(255, 255, 255)); 2669 SetTextColor (hdcBitmap, RGB(0, 0, 0)); 2670 PatBlt (hdcBitmap, nCopyCount * himl->cx, 0, 2671 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS); 2672 2672 #endif 2673 2673 DeleteObject (himl->hbmMask); … … 2709 2709 { 2710 2710 if (!himl) 2711 2711 return FALSE; 2712 2712 if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE)) 2713 2713 return FALSE; 2714 2714 if ((iImage!=-1) && ((iImage < 0) || (iImage > himl->cCurImage))) 2715 2715 return FALSE; 2716 2716 himl->nOvlIdx[iOverlay - 1] = iImage; 2717 2717 return TRUE; … … 2744 2744 { 2745 2745 if (!himl) 2746 return FALSE; 2747 2748 FIXME("empty stub!\n"); 2749 2746 2750 return FALSE; 2747 2748 FIXME("empty stub!\n"); 2749 2750 return FALSE; 2751 } 2752 2751 } 2752 -
trunk/src/comctl32/monthcal.c
r6705 r6709 1 1 /* Month calendar control 2 * 2 3 3 * 4 4 * Copyright 1998, 1999 Eric Kohl (ekohl@abo.rhein-zeitung.de) 5 5 * Copyright 1999 Alex Priem (alexp@sci.kun.nl) 6 6 * Copyright 1999 Chris Morgan <cmorgan@wpi.edu> and 7 * 7 * James Abbatiello <abbeyj@wpi.edu> 8 8 * Copyright 2000 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de> 9 9 * … … 13 13 * 14 14 * FIXME: handle resources better (doesn't work now); also take care 15 * of internationalization.15 of internationalization. 16 16 * FIXME: keyboard handling. 17 17 */ … … 43 43 DEFAULT_DEBUG_CHANNEL(monthcal); 44 44 45 #define MC_SEL_LBUTUP 1/* Left button released */46 #define MC_SEL_LBUTDOWN 2/* Left button pressed in calendar */45 #define MC_SEL_LBUTUP 1 /* Left button released */ 46 #define MC_SEL_LBUTDOWN 2 /* Left button pressed in calendar */ 47 47 #define MC_PREVPRESSED 4 /* Prev month button pressed */ 48 48 #define MC_NEXTPRESSED 8 /* Next month button pressed */ 49 #define MC_NEXTMONTHDELAY 350 50 51 52 #define MC_NEXTMONTHTIMER 1 53 #define MC_PREVMONTHTIMER 2 49 #define MC_NEXTMONTHDELAY 350 /* when continuously pressing `next */ 50 /* month', wait 500 ms before going */ 51 /* to the next month */ 52 #define MC_NEXTMONTHTIMER 1 /* Timer ID's */ 53 #define MC_PREVMONTHTIMER 2 54 54 55 55 typedef struct … … 58 58 COMCTL32_HEADER header; 59 59 #endif 60 COLORREF 61 COLORREF 62 COLORREF 63 COLORREF 64 COLORREF 65 COLORREF 66 HFONT 67 HFONT 68 int 69 int 70 int 71 int 72 int 73 int 74 int 75 int delta;/* scroll rate; # of months that the */60 COLORREF bk; 61 COLORREF txt; 62 COLORREF titlebk; 63 COLORREF titletxt; 64 COLORREF monthbk; 65 COLORREF trailingtxt; 66 HFONT hFont; 67 HFONT hBoldFont; 68 int textHeight; 69 int textWidth; 70 int height_increment; 71 int width_increment; 72 int left_offset; 73 int top_offset; 74 int firstDayplace; /* place of the first day of the current month */ 75 int delta; /* scroll rate; # of months that the */ 76 76 /* control moves when user clicks a scroll button */ 77 int visible;/* # of months visible */78 int firstDay;/* Start month calendar with firstDay's day */79 int 77 int visible; /* # of months visible */ 78 int firstDay; /* Start month calendar with firstDay's day */ 79 int monthRange; 80 80 MONTHDAYSTATE *monthdayState; 81 SYSTEMTIME 82 DWORD 83 DWORD 84 int status;/* See MC_SEL flags */85 int curSelDay;/* current selected day */86 int firstSelDay;/* first selected day */87 int 88 SYSTEMTIME 89 SYSTEMTIME 90 DWORD 91 SYSTEMTIME 92 SYSTEMTIME 93 94 RECT rcClient; 95 RECT rcDraw; 96 RECT title; 97 RECT titlebtnnext; 98 RECT titlebtnprev; /* the `prev month' button in the header */ 99 RECT titlemonth; 100 RECT titleyear; 101 RECT wdays; 102 RECT days; 103 RECT weeknums; 104 RECT todayrect; 81 SYSTEMTIME todaysDate; 82 DWORD currentMonth; 83 DWORD currentYear; 84 int status; /* See MC_SEL flags */ 85 int curSelDay; /* current selected day */ 86 int firstSelDay; /* first selected day */ 87 int maxSelCount; 88 SYSTEMTIME minSel; 89 SYSTEMTIME maxSel; 90 DWORD rangeValid; 91 SYSTEMTIME minDate; 92 SYSTEMTIME maxDate; 93 94 RECT rcClient; /* rect for whole client area */ 95 RECT rcDraw; /* rect for drawable portion of client area */ 96 RECT title; /* rect for the header above the calendar */ 97 RECT titlebtnnext; /* the `next month' button in the header */ 98 RECT titlebtnprev; /* the `prev month' button in the header */ 99 RECT titlemonth; /* the `month name' txt in the header */ 100 RECT titleyear; /* the `year number' txt in the header */ 101 RECT wdays; /* week days at top */ 102 RECT days; /* calendar area */ 103 RECT weeknums; /* week numbers at left side */ 104 RECT todayrect; /* `today: xx/xx/xx' text rect */ 105 105 HWND hWndYearEdit; /* Window Handle of edit box to handle years */ 106 106 HWND hWndYearUpDown;/* Window Handle of updown box to handle years */ … … 141 141 142 142 /* make sure that time is valid */ 143 static int MONTHCAL_ValidateTime(SYSTEMTIME time) 143 static int MONTHCAL_ValidateTime(SYSTEMTIME time) 144 144 { 145 145 if(time.wMonth > 12) return FALSE; 146 146 if(time.wDayOfWeek > 6) return FALSE; 147 147 if(time.wDay > MONTHCAL_MonthLength(time.wMonth, time.wYear)) 148 148 return FALSE; 149 149 if(time.wHour > 23) return FALSE; 150 150 if(time.wMinute > 59) return FALSE; … … 156 156 157 157 158 void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to) 158 void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to) 159 159 { 160 160 to->wYear = from->wYear; … … 169 169 170 170 171 /* Note:Depending on DST, this may be offset by a day. 171 /* Note:Depending on DST, this may be offset by a day. 172 172 Need to find out if we're on a DST place & adjust the clock accordingly. 173 173 Above function assumes we have a valid data. … … 182 182 year-=(month < 3); 183 183 184 return((year + year/4 - year/100 + year/400 + 184 return((year + year/4 - year/100 + year/400 + 185 185 DayOfWeekTable[month-1] + day - 1 ) % 7); 186 186 } … … 189 189 and day in the calendar. day== 0 mean the last day of tha last month 190 190 */ 191 static int MONTHCAL_CalcDayFromPos(MONTHCAL_INFO *infoPtr, int x, int y, 192 int *daypos,int *weekpos) 191 static int MONTHCAL_CalcDayFromPos(MONTHCAL_INFO *infoPtr, int x, int y, 192 int *daypos,int *weekpos) 193 193 { 194 194 int retval, firstDay; … … 202 202 *daypos = (x - infoPtr->days.left ) / infoPtr->width_increment; 203 203 *weekpos = (y - infoPtr->days.top ) / infoPtr->height_increment; 204 204 205 205 firstDay = (MONTHCAL_CalculateDayOfWeek(1, infoPtr->currentMonth, infoPtr->currentYear)+6 - infoPtr->firstDay)%7; 206 206 retval = *daypos + (7 * *weekpos) - firstDay; … … 211 211 /* sets x and y to be the position of the day */ 212 212 /* x == day, y == week where(0,0) == firstDay, 1st week */ 213 static void MONTHCAL_CalcDayXY(MONTHCAL_INFO *infoPtr, int day, int month, 213 static void MONTHCAL_CalcDayXY(MONTHCAL_INFO *infoPtr, int day, int month, 214 214 int *x, int *y) 215 215 { … … 227 227 if(prevMonth==0) 228 228 prevMonth = 12; 229 229 230 230 *x = (MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear) - firstDay) % 7; 231 231 *y = 0; … … 240 240 241 241 /* x: column(day), y: row(week) */ 242 static void MONTHCAL_CalcDayRect(MONTHCAL_INFO *infoPtr, RECT *r, int x, int y) 242 static void MONTHCAL_CalcDayRect(MONTHCAL_INFO *infoPtr, RECT *r, int x, int y) 243 243 { 244 244 r->left = infoPtr->days.left + x * infoPtr->width_increment; … … 252 252 /* day is the day value of the month(1 == 1st), month is the month */ 253 253 /* value(january == 1, december == 12) */ 254 static inline void MONTHCAL_CalcPosFromDay(MONTHCAL_INFO *infoPtr, 254 static inline void MONTHCAL_CalcPosFromDay(MONTHCAL_INFO *infoPtr, 255 255 int day, int month, RECT *r) 256 256 { … … 278 278 x = day_rect.left; 279 279 y = day_rect.top; 280 280 281 281 points[0].x = x; 282 282 points[0].y = y - 1; … … 287 287 points[3].x = x + infoPtr->width_increment; 288 288 points[3].y = y + 0.5 * infoPtr->height_increment; 289 289 290 290 points[4].x = x + infoPtr->width_increment; 291 291 points[4].y = y + 0.9 * infoPtr->height_increment; … … 294 294 points[6].x = x + 0.5 * infoPtr->width_increment; 295 295 points[6].y = y + 0.9 * infoPtr->height_increment; /* bring the bottom up just 296 297 296 a hair to fit inside the day rectangle */ 297 298 298 points[7].x = x + 0.2 * infoPtr->width_increment; 299 299 points[7].y = y + 0.8 * infoPtr->height_increment; … … 309 309 points[12].x = x + 0.4 * infoPtr->width_increment; 310 310 points[12].y = y + 0.2 * infoPtr->height_increment; 311 311 312 312 PolyBezier(hdc, points, 13); 313 313 DeleteObject(hRedPen); … … 329 329 sprintf(buf, "%d", day); 330 330 331 /* No need to check styles: when selection is not valid, it is set to zero. 331 /* No need to check styles: when selection is not valid, it is set to zero. 332 332 * 1<day<31, so evertyhing's OK. 333 333 */ … … 349 349 350 350 /* FIXME: this may need to be changed now b/c of the other 351 351 drawing changes 11/3/99 CMM */ 352 352 r2.left = r.left - 0.25 * infoPtr->textWidth; 353 353 r2.top = r.top; … … 390 390 391 391 /* CHECKME: For `todays date', do we need to check the locale?*/ 392 static void MONTHCAL_Refresh(HWND hwnd, HDC hdc, PAINTSTRUCT* ps) 392 static void MONTHCAL_Refresh(HWND hwnd, HDC hdc, PAINTSTRUCT* ps) 393 393 { 394 394 MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd); … … 425 425 hbr = CreateSolidBrush (infoPtr->bk); 426 426 FillRect(hdc, rcClient, hbr); 427 DeleteObject(hbr); 427 DeleteObject(hbr); 428 428 429 429 /* draw header */ … … 434 434 DeleteObject(hbr); 435 435 } 436 436 437 437 /* if the previous button is pressed draw it depressed */ 438 438 if(IntersectRect(&rcTemp, &(ps->rcPaint), prev)) 439 { 439 { 440 440 if((infoPtr->status & MC_PREVPRESSED)) 441 441 DrawFrameControl(hdc, prev, DFC_SCROLL, 442 442 DFCS_SCROLLLEFT | DFCS_PUSHED | 443 443 (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0)); 444 444 else /* if the previous button is pressed draw it depressed */ 445 445 DrawFrameControl(hdc, prev, DFC_SCROLL, 446 447 } 448 449 /* if next button is depressed draw it depressed */ 446 DFCS_SCROLLLEFT |(dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0)); 447 } 448 449 /* if next button is depressed draw it depressed */ 450 450 if(IntersectRect(&rcTemp, &(ps->rcPaint), next)) 451 451 { 452 452 if((infoPtr->status & MC_NEXTPRESSED)) 453 453 DrawFrameControl(hdc, next, DFC_SCROLL, 454 454 DFCS_SCROLLRIGHT | DFCS_PUSHED | 455 455 (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0)); 456 456 else /* if the next button is pressed draw it depressed */ … … 466 466 titlemonth->left = title->left; 467 467 titlemonth->right = title->right; 468 468 469 469 GetLocaleInfoA( LOCALE_USER_DEFAULT,LOCALE_SMONTHNAME1+infoPtr->currentMonth -1, 470 470 buf1,sizeof(buf1)); 471 471 sprintf(buf, "%s %ld", buf1, infoPtr->currentYear); 472 472 473 473 if(IntersectRect(&rcTemp, &(ps->rcPaint), titlemonth)) 474 474 { 475 DrawTextA(hdc, buf, strlen(buf), titlemonth, 475 DrawTextA(hdc, buf, strlen(buf), titlemonth, 476 476 DT_CENTER | DT_VCENTER | DT_SINGLELINE); 477 477 } … … 481 481 /* titlemonth left/right contained rect for whole titletxt('June 1999') 482 482 * MCM_HitTestInfo wants month & year rects, so prepare these now. 483 *(no, we can't draw them separately; the whole text is centered) 483 *(no, we can't draw them separately; the whole text is centered) 484 484 */ 485 485 GetTextExtentPoint32A(hdc, buf, strlen(buf), &size); … … 489 489 titlemonth->right = titlemonth->left + size.cx; 490 490 titleyear->left = titlemonth->right; 491 491 492 492 /* draw month area */ 493 493 rcTemp.top=infoPtr->wdays.top; … … 501 501 DeleteObject(hbr); 502 502 } 503 503 504 504 /* draw line under day abbreviatons */ 505 505 506 506 MoveToEx(hdc, infoPtr->days.left + 3, title->bottom + textHeight + 1, NULL); 507 507 508 508 LineTo(hdc, rcDraw->right - 3, title->bottom + textHeight + 1); 509 509 510 510 prevMonth = infoPtr->currentMonth - 1; 511 511 if(prevMonth == 0) /* if currentMonth is january(1) prevMonth is */ … … 529 529 for(j=0; j<7; j++) { 530 530 GetLocaleInfoA( LOCALE_USER_DEFAULT,LOCALE_SABBREVDAYNAME1 + (i +j)%7, 531 531 buf,sizeof(buf)); 532 532 DrawTextA(hdc, buf, strlen(buf), days, 533 533 DT_CENTER | DT_VCENTER | DT_SINGLELINE ); … … 537 537 538 538 /* draw day numbers; first, the previous month */ 539 539 540 540 firstDay = MONTHCAL_CalculateDayOfWeek(1, infoPtr->currentMonth, infoPtr->currentYear); 541 542 day = MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear) + 541 542 day = MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear) + 543 543 (infoPtr->firstDay + 7 - firstDay)%7 + 1; 544 544 if (day > MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear)) … … 553 553 if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay)) 554 554 { 555 MONTHCAL_DrawDay(hdc, infoPtr, day, prevMonth, i, 0, 555 MONTHCAL_DrawDay(hdc, infoPtr, day, prevMonth, i, 0, 556 556 infoPtr->monthdayState[m] & mask); 557 557 } … … 577 577 { 578 578 579 MONTHCAL_DrawDay(hdc, infoPtr, day, infoPtr->currentMonth, i, 0, 580 579 MONTHCAL_DrawDay(hdc, infoPtr, day, infoPtr->currentMonth, i, 0, 580 infoPtr->monthdayState[m] & mask); 581 581 582 582 if((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) && 583 583 (day==infoPtr->todaysDate.wDay) && 584 584 (infoPtr->currentYear == infoPtr->todaysDate.wYear)) { 585 585 if(!(dwStyle & MCS_NOTODAYCIRCLE)) 586 586 MONTHCAL_CircleDay(hdc, infoPtr, day, infoPtr->currentMonth); 587 587 } 588 588 } … … 595 595 j = 1; /* move to the 2nd week of the current month */ 596 596 i = 0; /* move back to sunday */ 597 while(day <= MONTHCAL_MonthLength(infoPtr->currentMonth, infoPtr->currentYear)) { 597 while(day <= MONTHCAL_MonthLength(infoPtr->currentMonth, infoPtr->currentYear)) { 598 598 MONTHCAL_CalcDayRect(infoPtr, &rcDay, i, j); 599 599 if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay)) … … 604 604 if((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) && 605 605 (day==infoPtr->todaysDate.wDay) && 606 (infoPtr->currentYear == infoPtr->todaysDate.wYear)) 607 if(!(dwStyle & MCS_NOTODAYCIRCLE)) 608 606 (infoPtr->currentYear == infoPtr->todaysDate.wYear)) 607 if(!(dwStyle & MCS_NOTODAYCIRCLE)) 608 MONTHCAL_CircleDay(hdc, infoPtr, day, infoPtr->currentMonth); 609 609 } 610 610 mask<<=1; … … 627 627 MONTHCAL_CalcDayRect(infoPtr, &rcDay, i, j); 628 628 if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay)) 629 { 629 { 630 630 MONTHCAL_DrawDay(hdc, infoPtr, day, infoPtr->currentMonth + 1, i, j, 631 631 infoPtr->monthdayState[m] & mask); 632 632 } 633 633 634 634 mask<<=1; 635 635 day++; 636 i++; 636 i++; 637 637 if(i==7) { /* past saturday, go to next week's sunday */ 638 638 i = 0; … … 650 650 if(!(dwStyle & MCS_NOTODAYCIRCLE)) { 651 651 /*day is the number of days from nextmonth we put on the calendar */ 652 MONTHCAL_CircleDay(hdc, infoPtr, 653 day+MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear), 654 652 MONTHCAL_CircleDay(hdc, infoPtr, 653 day+MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear), 654 infoPtr->currentMonth); 655 655 offset+=textWidth; 656 656 } 657 657 if (!LoadStringA(COMCTL32_hModule,IDM_TODAY,buf1,sizeof(buf1))) 658 658 { 659 660 659 WARN("Can't load resource\n"); 660 strcpy(buf1,"Today:"); 661 661 } 662 662 MONTHCAL_CalcDayRect(infoPtr, &rtoday, 1, 6); … … 674 674 } 675 675 676 /*eventually draw week numbers*/ 676 /*eventually draw week numbers*/ 677 677 if(dwStyle & MCS_WEEKNUMBERS) { 678 678 /* display weeknumbers*/ … … 682 682 LOCALE_IFIRSTWEEKOFYEAR == 0 (e.g US?): 683 683 The week containing Jan 1 is the first week of year 684 LOCALE_IFIRSTWEEKOFYEAR == 2 (e.g. Germany): 684 LOCALE_IFIRSTWEEKOFYEAR == 2 (e.g. Germany): 685 685 First week of year must contain 4 days of the new year 686 686 LOCALE_IFIRSTWEEKOFYEAR == 1 (what contries?) … … 688 688 */ 689 689 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IFIRSTWEEKOFYEAR, 690 690 buf, sizeof(buf)); 691 691 sscanf(buf, "%d", &weeknum); 692 692 switch (weeknum) 693 693 { 694 694 case 1: mindays = 6; 695 695 break; 696 696 case 2: mindays = 3; 697 697 break; 698 698 case 0: 699 699 default: 700 700 mindays = 0; 701 701 } 702 702 if (infoPtr->currentMonth < 2) 703 703 { 704 705 706 if ((infoPtr->firstDay +7 - weeknum1)%7 > mindays) 707 708 709 710 711 for(i=0; i<11; i++) 712 713 714 715 716 717 718 704 /* calculate all those exceptions for january */ 705 weeknum1=MONTHCAL_CalculateDayOfWeek(1,1,infoPtr->currentYear); 706 if ((infoPtr->firstDay +7 - weeknum1)%7 > mindays) 707 weeknum =1; 708 else 709 { 710 weeknum = 0; 711 for(i=0; i<11; i++) 712 weeknum+=MONTHCAL_MonthLength(i+1, infoPtr->currentYear-1); 713 weeknum +=startofprescal+ 7; 714 weeknum /=7; 715 weeknum1=MONTHCAL_CalculateDayOfWeek(1,1,infoPtr->currentYear-1); 716 if ((infoPtr->firstDay + 7 - weeknum1)%7 > mindays) 717 weeknum++; 718 } 719 719 } 720 720 else 721 721 { 722 723 for(i=0; i<prevMonth-1; i++) 724 725 726 727 728 729 722 weeknum = 0; 723 for(i=0; i<prevMonth-1; i++) 724 weeknum+=MONTHCAL_MonthLength(i+1, infoPtr->currentYear); 725 weeknum +=startofprescal+ 7; 726 weeknum /=7; 727 weeknum1=MONTHCAL_CalculateDayOfWeek(1,1,infoPtr->currentYear); 728 if ((infoPtr->firstDay + 7 - weeknum1)%7 > mindays) 729 weeknum++; 730 730 } 731 731 days->left = infoPtr->weeknums.left; … … 735 735 for(i=0; i<6; i++) { 736 736 if((i==0)&&(weeknum>50)) 737 738 739 740 737 { 738 sprintf(buf, "%d", weeknum); 739 weeknum=0; 740 } 741 741 else if((i==5)&&(weeknum>47)) 742 743 744 742 { 743 sprintf(buf, "%d", 1); 744 } 745 745 else 746 746 sprintf(buf, "%d", weeknum + i); 747 747 DrawTextA(hdc, buf, -1, days, DT_CENTER | DT_VCENTER | DT_SINGLELINE ); 748 748 days->top+=infoPtr->height_increment; 749 749 days->bottom+=infoPtr->height_increment; 750 750 } 751 751 752 752 MoveToEx(hdc, infoPtr->weeknums.right, infoPtr->weeknums.top + 3 , NULL); 753 753 LineTo(hdc, infoPtr->weeknums.right, infoPtr->weeknums.bottom ); 754 754 755 755 } 756 756 /* currentFont was font at entering Refresh */ 757 757 758 758 SetBkColor(hdc, oldBkColor); 759 SelectObject(hdc, currentFont); 759 SelectObject(hdc, currentFont); 760 760 SetTextColor(hdc, oldTextColor); 761 761 } 762 762 763 763 764 static LRESULT 764 static LRESULT 765 765 MONTHCAL_GetMinReqRect(HWND hwnd, WPARAM wParam, LPARAM lParam) 766 766 { … … 768 768 LPRECT lpRect = (LPRECT) lParam; 769 769 TRACE("%x %lx\n", wParam, lParam); 770 770 771 771 /* validate parameters */ 772 772 … … 781 781 782 782 783 static LRESULT 783 static LRESULT 784 784 MONTHCAL_GetColor(HWND hwnd, WPARAM wParam, LPARAM lParam) 785 785 { … … 807 807 808 808 809 static LRESULT 809 static LRESULT 810 810 MONTHCAL_SetColor(HWND hwnd, WPARAM wParam, LPARAM lParam) 811 811 { … … 847 847 848 848 849 static LRESULT 849 static LRESULT 850 850 MONTHCAL_GetMonthDelta(HWND hwnd, WPARAM wParam, LPARAM lParam) 851 851 { … … 853 853 854 854 TRACE("%x %lx\n", wParam, lParam); 855 855 856 856 if(infoPtr->delta) 857 857 return infoPtr->delta; … … 861 861 862 862 863 static LRESULT 863 static LRESULT 864 864 MONTHCAL_SetMonthDelta(HWND hwnd, WPARAM wParam, LPARAM lParam) 865 865 { … … 868 868 869 869 TRACE("%x %lx\n", wParam, lParam); 870 870 871 871 infoPtr->delta = (int)wParam; 872 872 return prev; … … 874 874 875 875 876 static LRESULT 876 static LRESULT 877 877 MONTHCAL_GetFirstDayOfWeek(HWND hwnd, WPARAM wParam, LPARAM lParam) 878 878 { 879 879 MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd); 880 880 881 881 return infoPtr->firstDay; 882 882 } … … 887 887 /* FIXME: this needs to be implemented properly in MONTHCAL_Refresh() */ 888 888 /* FIXME: we need more error checking here */ 889 static LRESULT 889 static LRESULT 890 890 MONTHCAL_SetFirstDayOfWeek(HWND hwnd, WPARAM wParam, LPARAM lParam) 891 891 { … … 903 903 { 904 904 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK, 905 905 buf, sizeof(buf)); 906 906 TRACE("%s %d\n", buf, strlen(buf)); 907 907 if(sscanf(buf, "%d", &day) == 1) 908 908 infoPtr->firstDay = day; 909 909 else 910 910 infoPtr->firstDay = 0; 911 911 } 912 912 return prev; … … 916 916 /* FIXME: fill this in */ 917 917 static LRESULT 918 MONTHCAL_GetMonthRange(HWND hwnd, WPARAM wParam, LPARAM lParam) 918 MONTHCAL_GetMonthRange(HWND hwnd, WPARAM wParam, LPARAM lParam) 919 919 { 920 920 MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd); … … 937 937 938 938 /* FIXME: are validated times taken from current date/time or simply 939 * copied? 939 * copied? 940 940 * FIXME: check whether MCM_GETMONTHRANGE shows correct result after 941 941 * adjusting range with MCM_SETRANGE … … 950 950 951 951 TRACE("%x %lx\n", wParam, lParam); 952 952 953 953 if(wParam & GDTR_MAX) { 954 954 if(MONTHCAL_ValidateTime(lprgSysTimeArray[1])){ … … 973 973 infoPtr->monthRange = infoPtr->maxDate.wMonth - infoPtr->minDate.wMonth; 974 974 975 if(infoPtr->monthRange!=prev) { 976 COMCTL32_ReAlloc(infoPtr->monthdayState, 977 975 if(infoPtr->monthRange!=prev) { 976 COMCTL32_ReAlloc(infoPtr->monthdayState, 977 infoPtr->monthRange * sizeof(MONTHDAYSTATE)); 978 978 } 979 979 … … 983 983 984 984 /* CHECKME: At the moment, we copy ranges anyway,regardless of 985 * infoPtr->rangeValid; a invalid range is simply filled with zeros in 985 * infoPtr->rangeValid; a invalid range is simply filled with zeros in 986 986 * SetRange. Is this the right behavior? 987 987 */ … … 1015 1015 if(iMonths!=infoPtr->monthRange) return 0; 1016 1016 1017 for(i=0; i<iMonths; i++) 1017 for(i=0; i<iMonths; i++) 1018 1018 infoPtr->monthdayState[i] = dayStates[i]; 1019 1019 return 1; 1020 1020 } 1021 1021 1022 static LRESULT 1022 static LRESULT 1023 1023 MONTHCAL_GetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam) 1024 1024 { … … 1036 1036 /* FIXME: if the specified date is not visible, make it visible */ 1037 1037 /* FIXME: redraw? */ 1038 static LRESULT 1038 static LRESULT 1039 1039 MONTHCAL_SetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam) 1040 1040 { … … 1057 1057 1058 1058 1059 static LRESULT 1059 static LRESULT 1060 1060 MONTHCAL_GetMaxSelCount(HWND hwnd, WPARAM wParam, LPARAM lParam) 1061 1061 { … … 1067 1067 1068 1068 1069 static LRESULT 1069 static LRESULT 1070 1070 MONTHCAL_SetMaxSelCount(HWND hwnd, WPARAM wParam, LPARAM lParam) 1071 1071 { … … 1081 1081 1082 1082 1083 static LRESULT 1083 static LRESULT 1084 1084 MONTHCAL_GetSelRange(HWND hwnd, WPARAM wParam, LPARAM lParam) 1085 1085 { … … 1100 1100 return TRUE; 1101 1101 } 1102 1102 1103 1103 return FALSE; 1104 1104 } 1105 1105 1106 1106 1107 static LRESULT 1107 static LRESULT 1108 1108 MONTHCAL_SetSelRange(HWND hwnd, WPARAM wParam, LPARAM lParam) 1109 1109 { … … 1124 1124 return TRUE; 1125 1125 } 1126 1126 1127 1127 return FALSE; 1128 1128 } 1129 1129 1130 1130 1131 static LRESULT 1131 static LRESULT 1132 1132 MONTHCAL_GetToday(HWND hwnd, WPARAM wParam, LPARAM lParam) 1133 1133 { … … 1145 1145 1146 1146 1147 static LRESULT 1147 static LRESULT 1148 1148 MONTHCAL_SetToday(HWND hwnd, WPARAM wParam, LPARAM lParam) 1149 1149 { … … 1170 1170 DWORD retval; 1171 1171 int day,wday,wnum; 1172 1173 1172 1173 1174 1174 x = lpht->pt.x; 1175 1175 y = lpht->pt.y; 1176 1176 retval = MCHT_NOWHERE; 1177 1178 1179 /* Comment in for debugging... 1180 TRACE("%d %d wd[%d %d %d %d] d[%d %d %d %d] t[%d %d %d %d] wn[%d %d %d %d]\n", x, y, 1181 1182 1183 1184 1185 1186 1187 1188 1177 1178 1179 /* Comment in for debugging... 1180 TRACE("%d %d wd[%d %d %d %d] d[%d %d %d %d] t[%d %d %d %d] wn[%d %d %d %d]\n", x, y, 1181 infoPtr->wdays.left, infoPtr->wdays.right, 1182 infoPtr->wdays.top, infoPtr->wdays.bottom, 1183 infoPtr->days.left, infoPtr->days.right, 1184 infoPtr->days.top, infoPtr->days.bottom, 1185 infoPtr->todayrect.left, infoPtr->todayrect.right, 1186 infoPtr->todayrect.top, infoPtr->todayrect.bottom, 1187 infoPtr->weeknums.left, infoPtr->weeknums.right, 1188 infoPtr->weeknums.top, infoPtr->weeknums.bottom); 1189 1189 */ 1190 1190 1191 1191 /* are we in the header? */ 1192 1192 1193 1193 if(PtInRect(&infoPtr->title, lpht->pt)) { 1194 1194 if(PtInRect(&infoPtr->titlebtnprev, lpht->pt)) { … … 1208 1208 goto done; 1209 1209 } 1210 1210 1211 1211 retval = MCHT_TITLE; 1212 1212 goto done; 1213 1213 } 1214 1214 1215 1215 day = MONTHCAL_CalcDayFromPos(infoPtr,x,y,&wday,&wnum); 1216 1216 if(PtInRect(&infoPtr->wdays, lpht->pt)) { … … 1218 1218 lpht->st.wYear = infoPtr->currentYear; 1219 1219 lpht->st.wMonth = (day < 1)? infoPtr->currentMonth -1 : infoPtr->currentMonth; 1220 lpht->st.wDay = (day < 1)? 1220 lpht->st.wDay = (day < 1)? 1221 1221 MONTHCAL_MonthLength(infoPtr->currentMonth-1,infoPtr->currentYear) -day : day; 1222 1222 goto done; 1223 1223 } 1224 if(PtInRect(&infoPtr->weeknums, lpht->pt)) { 1225 retval = MCHT_CALENDARWEEKNUM; 1224 if(PtInRect(&infoPtr->weeknums, lpht->pt)) { 1225 retval = MCHT_CALENDARWEEKNUM; 1226 1226 lpht->st.wYear = infoPtr->currentYear; 1227 lpht->st.wMonth = (day < 1) ? infoPtr->currentMonth -1 : 1228 (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear)) ? 1227 lpht->st.wMonth = (day < 1) ? infoPtr->currentMonth -1 : 1228 (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear)) ? 1229 1229 infoPtr->currentMonth +1 :infoPtr->currentMonth; 1230 lpht->st.wDay = (day < 1 ) ? 1231 MONTHCAL_MonthLength(infoPtr->currentMonth-1,infoPtr->currentYear) -day : 1232 (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear)) ? 1230 lpht->st.wDay = (day < 1 ) ? 1231 MONTHCAL_MonthLength(infoPtr->currentMonth-1,infoPtr->currentYear) -day : 1232 (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear)) ? 1233 1233 day - MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear) : day; 1234 goto done; 1235 } 1236 if(PtInRect(&infoPtr->days, lpht->pt)) 1234 goto done; 1235 } 1236 if(PtInRect(&infoPtr->days, lpht->pt)) 1237 1237 { 1238 1238 lpht->st.wYear = infoPtr->currentYear; 1239 if ( day < 1) 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1239 if ( day < 1) 1240 { 1241 retval = MCHT_CALENDARDATEPREV; 1242 lpht->st.wMonth = infoPtr->currentMonth - 1; 1243 if (lpht->st.wMonth <1) 1244 { 1245 lpht->st.wMonth = 12; 1246 lpht->st.wYear--; 1247 } 1248 lpht->st.wDay = MONTHCAL_MonthLength(lpht->st.wMonth,lpht->st.wYear) -day; 1249 } 1250 1250 else if (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear)) 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1251 { 1252 retval = MCHT_CALENDARDATENEXT; 1253 lpht->st.wMonth = infoPtr->currentMonth + 1; 1254 if (lpht->st.wMonth <12) 1255 { 1256 lpht->st.wMonth = 1; 1257 lpht->st.wYear++; 1258 } 1259 lpht->st.wDay = day - MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear) ; 1260 } 1261 1261 else { 1262 1263 1264 1262 retval = MCHT_CALENDARDATE; 1263 lpht->st.wMonth = infoPtr->currentMonth; 1264 lpht->st.wDay = day; 1265 1265 } 1266 1266 goto done; 1267 1267 } 1268 1268 if(PtInRect(&infoPtr->todayrect, lpht->pt)) { 1269 retval = MCHT_TODAYLINK; 1269 retval = MCHT_TODAYLINK; 1270 1270 goto done; 1271 1271 } 1272 1273 1272 1273 1274 1274 /* Hit nothing special? What's left must be background :-) */ 1275 1276 retval = MCHT_CALENDARBK; 1277 done: 1275 1276 retval = MCHT_CALENDARBK; 1277 done: 1278 1278 lpht->uHit = retval; 1279 1279 return retval; … … 1300 1300 nmds.nmhdr.idFrom = GetWindowLongA(hwnd, GWL_ID); 1301 1301 nmds.nmhdr.code = MCN_GETDAYSTATE; 1302 nmds.cDayState 1303 nmds.prgDayState 1302 nmds.cDayState = infoPtr->monthRange; 1303 nmds.prgDayState = COMCTL32_Alloc(infoPtr->monthRange * sizeof(MONTHDAYSTATE)); 1304 1304 1305 1305 SendMessageA(GetParent(hwnd), WM_NOTIFY, … … 1330 1330 nmds.nmhdr.idFrom = GetWindowLongA(hwnd, GWL_ID); 1331 1331 nmds.nmhdr.code = MCN_GETDAYSTATE; 1332 nmds.cDayState 1333 nmds.prgDayState = COMCTL32_Alloc1332 nmds.cDayState = infoPtr->monthRange; 1333 nmds.prgDayState = COMCTL32_Alloc 1334 1334 (infoPtr->monthRange * sizeof(MONTHDAYSTATE)); 1335 1335 … … 1348 1348 POINT menupoint; 1349 1349 char buf[32]; 1350 1350 1351 1351 hMenu = CreatePopupMenu(); 1352 1352 if (!LoadStringA(COMCTL32_hModule,IDM_GOTODAY,buf,sizeof(buf))) … … 1360 1360 ClientToScreen(hwnd, &menupoint); 1361 1361 if( TrackPopupMenu(hMenu,TPM_RIGHTBUTTON| TPM_NONOTIFY|TPM_RETURNCMD, 1362 1362 menupoint.x,menupoint.y,0,hwnd,NULL)) 1363 1363 { 1364 1364 infoPtr->currentMonth=infoPtr->todaysDate.wMonth; 1365 1365 infoPtr->currentYear=infoPtr->todaysDate.wYear; 1366 1366 InvalidateRect(hwnd, NULL, FALSE); 1367 } 1367 } 1368 1368 return 0; 1369 1369 } … … 1381 1381 POINT menupoint; 1382 1382 TRACE("%x %lx\n", wParam, lParam); 1383 1383 1384 1384 if (infoPtr->hWndYearUpDown) 1385 1385 { 1386 1386 infoPtr->currentYear=SendMessageA( infoPtr->hWndYearUpDown, UDM_SETPOS, (WPARAM) 0,(LPARAM)0); 1387 1387 if(!DestroyWindow(infoPtr->hWndYearUpDown)) 1388 1389 1390 1388 { 1389 FIXME("Can't destroy Updown Control\n"); 1390 } 1391 1391 else 1392 1392 infoPtr->hWndYearUpDown=0; 1393 1393 if(!DestroyWindow(infoPtr->hWndYearEdit)) 1394 1395 1396 1394 { 1395 FIXME("Can't destroy Updown Control\n"); 1396 } 1397 1397 else 1398 1398 infoPtr->hWndYearEdit=0; 1399 1399 InvalidateRect(hwnd, NULL, FALSE); 1400 1400 } 1401 1401 1402 1402 ht.pt.x = (INT)LOWORD(lParam); 1403 1403 ht.pt.y = (INT)HIWORD(lParam); … … 1414 1414 return TRUE; 1415 1415 } 1416 if(hit == MCHT_TITLEBTNPREV){ 1416 if(hit == MCHT_TITLEBTNPREV){ 1417 1417 MONTHCAL_GoToPrevMonth(hwnd, infoPtr); 1418 1418 infoPtr->status = MC_PREVPRESSED; … … 1424 1424 if(hit == MCHT_TITLEMONTH) { 1425 1425 hMenu = CreatePopupMenu(); 1426 1426 1427 1427 for (i=0; i<12;i++) 1428 1428 { 1429 1430 1431 1429 GetLocaleInfoA( LOCALE_USER_DEFAULT,LOCALE_SMONTHNAME1+i, 1430 buf,sizeof(buf)); 1431 AppendMenuA(hMenu, MF_STRING|MF_ENABLED,i+1, buf); 1432 1432 } 1433 1433 menupoint.x=infoPtr->titlemonth.right; … … 1435 1435 ClientToScreen(hwnd, &menupoint); 1436 1436 i= TrackPopupMenu(hMenu,TPM_LEFTALIGN | TPM_NONOTIFY | TPM_RIGHTBUTTON | TPM_RETURNCMD, 1437 1437 menupoint.x,menupoint.y,0,hwnd,NULL); 1438 1438 if ((i>0) && (i<13)) 1439 1439 { 1440 1441 1440 infoPtr->currentMonth=i; 1441 InvalidateRect(hwnd, NULL, FALSE); 1442 1442 } 1443 1443 } 1444 1444 if(hit == MCHT_TITLEYEAR) { 1445 1445 infoPtr->hWndYearEdit=CreateWindowExA(0, 1446 1447 1448 1449 1450 1451 1452 1453 (HMENU)NULL, 1454 (HINSTANCE)NULL, 1455 1446 "EDIT", 1447 0, 1448 WS_VISIBLE | WS_CHILD |UDS_SETBUDDYINT, 1449 infoPtr->titleyear.left+3,infoPtr->titlebtnnext.top, 1450 infoPtr->titleyear.right-infoPtr->titleyear.left, 1451 infoPtr->textHeight, 1452 hwnd, 1453 (HMENU)NULL, 1454 (HINSTANCE)NULL, 1455 NULL); 1456 1456 infoPtr->hWndYearUpDown=CreateWindowExA(0, 1457 1458 1459 1460 1461 1462 1463 1464 (HMENU)NULL, 1465 (HINSTANCE)NULL, 1466 1457 UPDOWN_CLASSA, 1458 0, 1459 WS_VISIBLE | WS_CHILD |UDS_SETBUDDYINT|UDS_NOTHOUSANDS|UDS_ARROWKEYS, 1460 infoPtr->titleyear.right+6,infoPtr->titlebtnnext.top, 1461 20, 1462 infoPtr->textHeight, 1463 hwnd, 1464 (HMENU)NULL, 1465 (HINSTANCE)NULL, 1466 NULL); 1467 1467 SendMessageA( infoPtr->hWndYearUpDown, UDM_SETRANGE, (WPARAM) 0, MAKELONG (9999, 1753)); 1468 1468 SendMessageA( infoPtr->hWndYearUpDown, UDM_SETBUDDY, (WPARAM) infoPtr->hWndYearEdit, (LPARAM)0 ); 1469 1469 SendMessageA( infoPtr->hWndYearUpDown, UDM_SETPOS, (WPARAM) 0,(LPARAM)infoPtr->currentYear ); 1470 1470 return TRUE; 1471 1471 1472 1472 } 1473 1473 if(hit == MCHT_TODAYLINK) { … … 1487 1487 MONTHCAL_CopyTime(&nmsc.stSelStart, &infoPtr->minSel); 1488 1488 MONTHCAL_CopyTime(&nmsc.stSelEnd, &infoPtr->maxSel); 1489 1489 1490 1490 SendMessageA(GetParent(hwnd), WM_NOTIFY, 1491 1491 (WPARAM)nmsc.nmhdr.idFrom,(LPARAM)&nmsc); … … 1493 1493 MONTHCAL_CopyTime(&ht.st, &selArray[0]); 1494 1494 MONTHCAL_CopyTime(&ht.st, &selArray[1]); 1495 MONTHCAL_SetSelRange(hwnd,0,(LPARAM) &selArray); 1495 MONTHCAL_SetSelRange(hwnd,0,(LPARAM) &selArray); 1496 1496 1497 1497 /* redraw both old and new days if the selected day changed */ … … 1546 1546 return TRUE; 1547 1547 } 1548 if(hit == MCHT_CALENDARDATEPREV){ 1548 if(hit == MCHT_CALENDARDATEPREV){ 1549 1549 MONTHCAL_GoToPrevMonth(hwnd, infoPtr); 1550 1550 InvalidateRect(hwnd, NULL, FALSE); … … 1564 1564 MONTHCAL_CopyTime(&nmsc.stSelStart, &infoPtr->minSel); 1565 1565 MONTHCAL_CopyTime(&nmsc.stSelEnd, &infoPtr->maxSel); 1566 1566 1567 1567 SendMessageA(GetParent(hwnd), WM_NOTIFY, 1568 1568 (WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc); 1569 1569 1570 1570 /* redraw if necessary */ 1571 1571 if(redraw) 1572 1572 InvalidateRect(hwnd, NULL, FALSE); 1573 1573 1574 1574 return 0; 1575 1575 } … … 1586 1586 1587 1587 switch(wParam) { 1588 case MC_NEXTMONTHTIMER: 1588 case MC_NEXTMONTHTIMER: 1589 1589 redraw = TRUE; 1590 1590 MONTHCAL_GoToNextMonth(hwnd, infoPtr); … … 1618 1618 ht.pt.x = LOWORD(lParam); 1619 1619 ht.pt.y = HIWORD(lParam); 1620 1620 1621 1621 hit = MONTHCAL_HitTest(hwnd, (LPARAM)&ht); 1622 1622 1623 1623 /* not on the calendar date numbers? bail out */ 1624 1624 TRACE("hit:%x\n",hit); … … 1638 1638 if(infoPtr->firstSelDay==selArray[0].wDay) i=1; 1639 1639 TRACE("oldRange:%d %d %d %d\n", infoPtr->firstSelDay, selArray[0].wDay, selArray[1].wDay, i); 1640 if(infoPtr->firstSelDay==selArray[1].wDay) { 1640 if(infoPtr->firstSelDay==selArray[1].wDay) { 1641 1641 /* 1st time we get here: selArray[0]=selArray[1]) */ 1642 1642 /* if we're still at the first selected date, return */ … … 1644 1644 if(selday<infoPtr->firstSelDay) i = 0; 1645 1645 } 1646 1646 1647 1647 if(abs(infoPtr->firstSelDay - selday) >= infoPtr->maxSelCount) { 1648 1648 if(selday>infoPtr->firstSelDay) … … 1651 1651 selday = infoPtr->firstSelDay - infoPtr->maxSelCount; 1652 1652 } 1653 1653 1654 1654 if(selArray[i].wDay!=selday) { 1655 1655 TRACE("newRange:%d %d %d %d\n", infoPtr->firstSelDay, selArray[0].wDay, selArray[1].wDay, i); 1656 1656 1657 1657 selArray[i].wDay = selday; 1658 1658 … … 1712 1712 { 1713 1713 TRACE("\n"); 1714 1714 1715 1715 InvalidateRect(hwnd, NULL, FALSE); 1716 1716 … … 1769 1769 1770 1770 /* recalculate the height and width increments and offsets */ 1771 /* FIXME: We use up all available width. This will inhibit having multiple 1772 calendars in a row, like win doesn 1771 /* FIXME: We use up all available width. This will inhibit having multiple 1772 calendars in a row, like win doesn 1773 1773 */ 1774 1774 if(dwStyle & MCS_WEEKNUMBERS) … … 1776 1776 else 1777 1777 xdiv=7.0; 1778 infoPtr->width_increment = (infoPtr->rcDraw.right - infoPtr->rcDraw.left) / xdiv; 1779 infoPtr->height_increment = (infoPtr->rcDraw.bottom - infoPtr->rcDraw.top) / 10.0; 1778 infoPtr->width_increment = (infoPtr->rcDraw.right - infoPtr->rcDraw.left) / xdiv; 1779 infoPtr->height_increment = (infoPtr->rcDraw.bottom - infoPtr->rcDraw.top) / 10.0; 1780 1780 infoPtr->left_offset = (infoPtr->rcDraw.right - infoPtr->rcDraw.left) - (infoPtr->width_increment * xdiv); 1781 1781 infoPtr->top_offset = (infoPtr->rcDraw.bottom - infoPtr->rcDraw.top) - (infoPtr->height_increment * 10.0); … … 1790 1790 rcDraw->bottom = rcDraw->top + 9 * infoPtr->textHeight + 5; 1791 1791 }*/ 1792 1792 1793 1793 /* calculate title area */ 1794 1794 title->top = rcClient->top; … … 1805 1805 next->right = title->right - 6; 1806 1806 next->left = next->right - (title->bottom - title->top); 1807 1807 1808 1808 /* titlemonth->left and right change based upon the current month */ 1809 1809 /* and are recalculated in refresh as the current month may change */ … … 1811 1811 titlemonth->top = titleyear->top = title->top + (infoPtr->height_increment)/2; 1812 1812 titlemonth->bottom = titleyear->bottom = title->bottom - (infoPtr->height_increment)/2; 1813 1813 1814 1814 /* setup the dimensions of the rectangle we draw the names of the */ 1815 1815 /* days of the week in */ 1816 1816 weeknumrect->left =infoPtr->left_offset; 1817 if(dwStyle & MCS_WEEKNUMBERS) 1817 if(dwStyle & MCS_WEEKNUMBERS) 1818 1818 weeknumrect->right=prev->right; 1819 1819 else … … 1823 1823 wdays->top = title->bottom ; 1824 1824 wdays->bottom = wdays->top + infoPtr->height_increment; 1825 1825 1826 1826 days->top = weeknumrect->top = wdays->bottom ; 1827 1827 days->bottom = weeknumrect->bottom = days->top + 6 * infoPtr->height_increment; 1828 1828 1829 1829 todayrect->left = rcClient->left; 1830 1830 todayrect->right = rcClient->right; … … 1832 1832 todayrect->bottom = days->bottom + infoPtr->height_increment; 1833 1833 1834 /* uncomment for excessive debugging 1834 /* uncomment for excessive debugging 1835 1835 TRACE("dx=%d dy=%d rcC[%d %d %d %d] t[%d %d %d %d] wd[%d %d %d %d] w[%d %d %d %d] t[%d %d %d %d]\n", 1836 1837 1838 1839 1840 1841 1836 infoPtr->width_increment,infoPtr->height_increment, 1837 rcClient->left, rcClient->right, rcClient->top, rcClient->bottom, 1838 title->left, title->right, title->top, title->bottom, 1839 wdays->left, wdays->right, wdays->top, wdays->bottom, 1840 days->left, days->right, days->top, days->bottom, 1841 todayrect->left,todayrect->right,todayrect->top,todayrect->bottom); 1842 1842 */ 1843 1843 1844 1844 /* restore the originally selected font */ 1845 SelectObject(hdc, currentFont); 1845 SelectObject(hdc, currentFont); 1846 1846 1847 1847 ReleaseDC(hwnd, hdc); … … 1865 1865 { 1866 1866 MONTHCAL_INFO *infoPtr; 1867 LOGFONTA 1867 LOGFONTA logFont; 1868 1868 1869 1869 /* allocate memory for info structure */ … … 1900 1900 infoPtr->maxSelCount = 7; 1901 1901 infoPtr->monthRange = 3; 1902 infoPtr->monthdayState = COMCTL32_Alloc 1902 infoPtr->monthdayState = COMCTL32_Alloc 1903 1903 (infoPtr->monthRange * sizeof(MONTHDAYSTATE)); 1904 1904 infoPtr->titlebk = GetSysColor(COLOR_ACTIVECAPTION); … … 1907 1907 infoPtr->trailingtxt = GetSysColor(COLOR_GRAYTEXT); 1908 1908 infoPtr->bk = GetSysColor(COLOR_WINDOW); 1909 infoPtr->txt 1909 infoPtr->txt = GetSysColor(COLOR_WINDOWTEXT); 1910 1910 1911 1911 /* call MONTHCAL_UpdateSize to set all of the dimensions */ … … 2062 2062 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 2063 2063 wndClass.lpszClassName = MONTHCAL_CLASSA; 2064 2064 2065 2065 RegisterClassA(&wndClass); 2066 2066 } -
trunk/src/comctl32/status.c
r6705 r6709 26 26 typedef struct 27 27 { 28 INT 29 INT 30 RECT 31 LPWSTR 28 INT x; 29 INT style; 30 RECT bound; 31 LPWSTR text; 32 32 HICON hIcon; 33 33 } STATUSWINDOWPART; … … 48 48 COLORREF clrBk; /* background color */ 49 49 BOOL bUnicode; /* unicode flag */ 50 STATUSWINDOWPART part0;/* simple window */50 STATUSWINDOWPART part0; /* simple window */ 51 51 STATUSWINDOWPART *parts; 52 52 } STATUSWINDOWINFO; … … 93 93 SelectObject (hdc, GetSysColorPen (COLOR_3DSHADOW)); 94 94 for (i = 1; i < 11; i += 4) { 95 96 97 98 99 95 MoveToEx (hdc, pt.x - i, pt.y, NULL); 96 LineTo (hdc, pt.x, pt.y - i); 97 98 MoveToEx (hdc, pt.x - i-1, pt.y, NULL); 99 LineTo (hdc, pt.x, pt.y - i-1); 100 100 } 101 101 102 102 SelectObject (hdc, GetSysColorPen (COLOR_3DHIGHLIGHT)); 103 103 for (i = 3; i < 13; i += 4) { 104 105 104 MoveToEx (hdc, pt.x - i, pt.y, NULL); 105 LineTo (hdc, pt.x, pt.y - i); 106 106 } 107 107 … … 110 110 111 111 112 static void 112 static void 113 113 STATUSBAR_DrawPart (HDC hdc, STATUSWINDOWPART *part) 114 114 { … … 126 126 /* draw the icon */ 127 127 if (part->hIcon) { 128 129 130 131 132 128 INT cy = r.bottom - r.top; 129 130 r.left += 2; 131 DrawIconEx (hdc, r.left, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL); 132 r.left += cy; 133 133 } 134 134 … … 139 139 UINT align = DT_LEFT; 140 140 if (*p == L'\t') { 141 142 143 144 145 146 147 141 p++; 142 align = DT_CENTER; 143 144 if (*p == L'\t') { 145 p++; 146 align = DT_RIGHT; 147 } 148 148 } 149 149 r.left += 3; … … 151 151 DrawTextW (hdc, p, -1, &r, align|DT_VCENTER|DT_SINGLELINE); 152 152 if (oldbkmode != TRANSPARENT) 153 153 SetBkMode(hdc, oldbkmode); 154 154 } 155 155 } … … 169 169 170 170 if (infoPtr->clrBk != CLR_DEFAULT) 171 171 hbrBk = CreateSolidBrush (infoPtr->clrBk); 172 172 else 173 173 hbrBk = GetSysColorBrush (COLOR_3DFACE); 174 174 FillRect(hdc, &part->bound, hbrBk); 175 175 … … 177 177 178 178 if (part->style & SBT_OWNERDRAW) { 179 180 181 182 183 184 185 186 187 188 179 DRAWITEMSTRUCT dis; 180 181 dis.CtlID = GetWindowLongA (hwnd, GWL_ID); 182 dis.itemID = itemID; 183 dis.hwndItem = hwnd; 184 dis.hDC = hdc; 185 dis.rcItem = part->bound; 186 dis.itemData = (INT)part->text; 187 SendMessageA (GetParent (hwnd), WM_DRAWITEM, 188 (WPARAM)dis.CtlID, (LPARAM)&dis); 189 189 } else 190 190 STATUSBAR_DrawPart (hdc, part); 191 191 192 192 SelectObject (hdc, hOldFont); 193 193 194 194 if (infoPtr->clrBk != CLR_DEFAULT) 195 195 DeleteObject (hbrBk); 196 196 197 197 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) { 198 199 200 201 198 RECT rect; 199 200 GetClientRect (hwnd, &rect); 201 STATUSBAR_DrawSizeGrip (hdc, &rect); 202 202 } 203 203 } … … 221 221 222 222 if (infoPtr->clrBk != CLR_DEFAULT) 223 223 hbrBk = CreateSolidBrush (infoPtr->clrBk); 224 224 else 225 225 hbrBk = GetSysColorBrush (COLOR_3DFACE); 226 226 FillRect(hdc, &rect, hbrBk); 227 227 … … 229 229 230 230 if (infoPtr->simple) { 231 231 STATUSBAR_RefreshPart (infoPtr, hwnd, &infoPtr->part0, hdc, 0); 232 232 } else { 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 233 for (i = 0; i < infoPtr->numParts; i++) { 234 if (infoPtr->parts[i].style & SBT_OWNERDRAW) { 235 DRAWITEMSTRUCT dis; 236 237 dis.CtlID = GetWindowLongA (hwnd, GWL_ID); 238 dis.itemID = i; 239 dis.hwndItem = hwnd; 240 dis.hDC = hdc; 241 dis.rcItem = infoPtr->parts[i].bound; 242 dis.itemData = (INT)infoPtr->parts[i].text; 243 SendMessageA (GetParent (hwnd), WM_DRAWITEM, 244 (WPARAM)dis.CtlID, (LPARAM)&dis); 245 } else 246 STATUSBAR_RefreshPart (infoPtr, hwnd, &infoPtr->parts[i], hdc, i); 247 } 248 248 } 249 249 … … 251 251 252 252 if (infoPtr->clrBk != CLR_DEFAULT) 253 253 DeleteObject (hbrBk); 254 254 255 255 if (GetWindowLongA(hwnd, GWL_STYLE) & SBARS_SIZEGRIP) 256 256 STATUSBAR_DrawSizeGrip (hdc, &rect); 257 257 258 258 return TRUE; … … 265 265 STATUSWINDOWPART *part; 266 266 RECT rect, *r; 267 int 267 int i; 268 268 269 269 /* get our window size */ … … 278 278 /* set bounds for non-simple rectangles */ 279 279 for (i = 0; i < infoPtr->numParts; i++) { 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 280 part = &infoPtr->parts[i]; 281 r = &infoPtr->parts[i].bound; 282 r->top = rect.top; 283 r->bottom = rect.bottom; 284 if (i == 0) 285 r->left = 0; 286 else 287 r->left = infoPtr->parts[i-1].bound.right + HORZ_GAP; 288 if (part->x == -1) 289 r->right = rect.right; 290 else 291 r->right = part->x; 292 293 if (infoPtr->hwndToolTip) { 294 TTTOOLINFOA ti; 295 296 ti.cbSize = sizeof(TTTOOLINFOA); 297 ti.hwnd = hwnd; 298 ti.uId = i; 299 ti.rect = *r; 300 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA, 301 0, (LPARAM)&ti); 302 } 303 303 } 304 304 } … … 307 307 static VOID 308 308 STATUSBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg, 309 309 WPARAM wParam, LPARAM lParam) 310 310 { 311 311 MSG msg; … … 345 345 TRACE("%d\n", nPart); 346 346 if ((nPart < -1) || (nPart >= infoPtr->numParts)) 347 347 return 0; 348 348 349 349 if (nPart == -1) … … 365 365 parts = (LPINT) lParam; 366 366 if (parts) { 367 368 369 367 for (i = 0; i < num_parts; i++) { 368 parts[i] = infoPtr->parts[i].x; 369 } 370 370 } 371 371 return (infoPtr->numParts); … … 376 376 STATUSBAR_GetRect (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam) 377 377 { 378 int 378 int nPart; 379 379 LPRECT rect; 380 380 … … 383 383 rect = (LPRECT) lParam; 384 384 if (infoPtr->simple) 385 385 *rect = infoPtr->part0.bound; 386 386 else 387 387 *rect = infoPtr->parts[nPart].bound; 388 388 return TRUE; 389 389 } … … 400 400 TRACE("part %d\n", nPart); 401 401 if (infoPtr->simple) 402 402 part = &infoPtr->part0; 403 403 else 404 404 #ifdef __WIN32OS2__ 405 405 { 406 406 if (nPart >= infoPtr->numParts) 407 408 407 return FALSE; 408 part = &infoPtr->parts[nPart]; 409 409 } 410 410 #else 411 411 part = &infoPtr->parts[nPart]; 412 412 #endif 413 413 414 414 if (part->style & SBT_OWNERDRAW) 415 415 result = (LRESULT)part->text; 416 416 else { 417 417 DWORD len = part->text ? WideCharToMultiByte( CP_ACP, 0, part->text, -1, … … 435 435 TRACE("part %d\n", nPart); 436 436 if (infoPtr->simple) 437 437 part = &infoPtr->part0; 438 438 else 439 439 #ifdef __WIN32OS2__ 440 440 { 441 441 if (nPart >= infoPtr->numParts) 442 443 442 return FALSE; 443 part = &infoPtr->parts[nPart]; 444 444 } 445 445 #else 446 446 part = &infoPtr->parts[nPart]; 447 447 #endif 448 448 449 449 if (part->style & SBT_OWNERDRAW) 450 450 result = (LRESULT)part->text; 451 451 else { 452 453 454 455 452 result = part->text ? strlenW (part->text) : 0; 453 result |= (part->style << 16); 454 if (part->text && lParam) 455 strcpyW ((LPWSTR)lParam, part->text); 456 456 } 457 457 return result; … … 471 471 472 472 if (infoPtr->simple) 473 473 part = &infoPtr->part0; 474 474 else 475 475 #ifdef __WIN32OS2__ 476 476 { 477 477 if (nPart >= infoPtr->numParts) 478 479 478 return FALSE; 479 part = &infoPtr->parts[nPart]; 480 480 } 481 481 #else 482 482 part = &infoPtr->parts[nPart]; 483 483 #endif 484 484 485 485 if (part->text) 486 486 result = strlenW(part->text); 487 487 else 488 488 result = 0; 489 489 490 490 result |= (part->style << 16); … … 526 526 buf[0]=0; 527 527 528 529 530 531 532 528 if (infoPtr->hwndToolTip) { 529 TTTOOLINFOW ti; 530 ti.cbSize = sizeof(TTTOOLINFOW); 531 ti.hwnd = hwnd; 532 ti.uId = LOWORD(wParam); 533 533 ti.lpszText = buf; 534 535 536 534 SendMessageW(infoPtr->hwndToolTip, TTM_GETTEXTW, 0, (LPARAM)&ti); 535 } 536 lstrcpynW(tip, buf, HIWORD(wParam)); 537 537 } 538 538 … … 575 575 576 576 if ((nPart < -1) || (nPart >= infoPtr->numParts)) 577 577 return FALSE; 578 578 579 579 TRACE("setting part %d, icon %lx\n",nPart,lParam); 580 580 581 581 if (nPart == -1) { 582 583 584 585 582 if (infoPtr->part0.hIcon == (HICON)lParam) /* same as - no redraw */ 583 return TRUE; 584 infoPtr->part0.hIcon = (HICON)lParam; 585 if (infoPtr->simple) 586 586 InvalidateRect(hwnd, &infoPtr->part0.bound, FALSE); 587 587 } else { 588 589 590 591 592 588 if (infoPtr->parts[nPart].hIcon == (HICON)lParam) /* same as - no redraw */ 589 return TRUE; 590 591 infoPtr->parts[nPart].hIcon = (HICON)lParam; 592 if (!(infoPtr->simple)) 593 593 InvalidateRect(hwnd, &infoPtr->parts[nPart].bound, FALSE); 594 594 } … … 603 603 TRACE("\n"); 604 604 if (IsWindowVisible (hwnd)) { 605 606 607 608 609 610 611 612 613 614 615 616 617 605 HWND parent = GetParent (hwnd); 606 INT width, x, y; 607 RECT parent_rect; 608 609 GetClientRect (parent, &parent_rect); 610 infoPtr->height = (INT)wParam + VERT_BORDER; 611 width = parent_rect.right - parent_rect.left; 612 x = parent_rect.left; 613 y = parent_rect.bottom - infoPtr->height; 614 MoveWindow (hwnd, parent_rect.left, 615 parent_rect.bottom - infoPtr->height, 616 width, infoPtr->height, TRUE); 617 STATUSBAR_SetPartBounds (infoPtr, hwnd); 618 618 } 619 619 … … 627 627 STATUSWINDOWPART *tmp; 628 628 LPINT parts; 629 int 630 int 629 int i; 630 int oldNumParts; 631 631 632 632 TRACE("(%d,%p)\n",wParam,(LPVOID)lParam); … … 634 634 /* FIXME: should return FALSE sometimes (maybe when wParam == 0 ?) */ 635 635 if (infoPtr->simple) 636 636 infoPtr->simple = FALSE; 637 637 638 638 oldNumParts = infoPtr->numParts; … … 640 640 parts = (LPINT) lParam; 641 641 if (oldNumParts > infoPtr->numParts) { 642 643 644 645 642 for (i = infoPtr->numParts ; i < oldNumParts; i++) { 643 if (infoPtr->parts[i].text && !(infoPtr->parts[i].style & SBT_OWNERDRAW)) 644 COMCTL32_Free (infoPtr->parts[i].text); 645 } 646 646 } 647 647 if (oldNumParts < infoPtr->numParts) { 648 649 650 651 652 653 654 648 tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * infoPtr->numParts); 649 for (i = 0; i < oldNumParts; i++) { 650 tmp[i] = infoPtr->parts[i]; 651 } 652 if (infoPtr->parts) 653 COMCTL32_Free (infoPtr->parts); 654 infoPtr->parts = tmp; 655 655 } 656 656 if (oldNumParts == infoPtr->numParts) { 657 658 659 660 661 662 } 663 657 for (i=0;i<oldNumParts;i++) 658 if (infoPtr->parts[i].x != parts[i]) 659 break; 660 if (i==oldNumParts) /* Unchanged? no need to redraw! */ 661 return TRUE; 662 } 663 664 664 for (i = 0; i < infoPtr->numParts; i++) 665 665 infoPtr->parts[i].x = parts[i]; 666 666 667 667 if (infoPtr->hwndToolTip) { 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 668 INT nTipCount = 669 SendMessageA (infoPtr->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0); 670 671 if (nTipCount < infoPtr->numParts) { 672 /* add tools */ 673 TTTOOLINFOA ti; 674 INT i; 675 676 ZeroMemory (&ti, sizeof(TTTOOLINFOA)); 677 ti.cbSize = sizeof(TTTOOLINFOA); 678 ti.hwnd = hwnd; 679 for (i = nTipCount; i < infoPtr->numParts; i++) { 680 TRACE("add tool %d\n", i); 681 ti.uId = i; 682 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 683 0, (LPARAM)&ti); 684 } 685 } 686 else if (nTipCount > infoPtr->numParts) { 687 /* delete tools */ 688 INT i; 689 690 for (i = nTipCount - 1; i >= infoPtr->numParts; i--) { 691 FIXME("delete tool %d\n", i); 692 } 693 } 694 694 } 695 695 STATUSBAR_SetPartBounds (infoPtr, hwnd); … … 703 703 { 704 704 STATUSWINDOWPART *part=NULL; 705 int 706 int 705 int nPart; 706 int style; 707 707 LPSTR text; 708 BOOL 708 BOOL changed = FALSE; 709 709 710 710 text = (LPSTR) lParam; … … 715 715 716 716 if (nPart==255) 717 717 part = &infoPtr->part0; 718 718 else if (!infoPtr->simple && infoPtr->parts!=NULL) 719 719 #ifdef __WIN32OS2__ 720 720 { 721 721 if (nPart >= infoPtr->numParts) 722 723 722 return FALSE; 723 part = &infoPtr->parts[nPart]; 724 724 } 725 725 #else 726 726 part = &infoPtr->parts[nPart]; 727 727 #endif 728 728 if (!part) return FALSE; 729 729 730 730 if (part->style != style) 731 731 changed = TRUE; 732 732 733 733 part->style = style; 734 734 if (style & SBT_OWNERDRAW) { 735 736 737 735 if (part->text == (LPWSTR)text) 736 return TRUE; 737 part->text = (LPWSTR)text; 738 738 } else { 739 740 741 742 739 LPWSTR ntext; 740 741 /* check if text is unchanged -> no need to redraw */ 742 if (text) { 743 743 DWORD len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 ); 744 744 LPWSTR tmptext = COMCTL32_Alloc(len*sizeof(WCHAR)); 745 745 MultiByteToWideChar( CP_ACP, 0, text, -1, tmptext, len ); 746 746 747 748 749 750 751 752 753 if (!changed && !part->text) 754 755 756 757 758 759 760 747 if (!changed && part->text && !lstrcmpW(tmptext,part->text)) { 748 COMCTL32_Free(tmptext); 749 return TRUE; 750 } 751 ntext = tmptext; 752 } else { 753 if (!changed && !part->text) 754 return TRUE; 755 ntext = 0; 756 } 757 758 if (part->text) 759 COMCTL32_Free (part->text); 760 part->text = ntext; 761 761 } 762 762 InvalidateRect(hwnd, &part->bound, FALSE); … … 780 780 TRACE("part %d -> '%s' with style %04x\n", nPart, debugstr_w(text), style); 781 781 if ((infoPtr->simple) || (infoPtr->parts==NULL) || (nPart==255)) 782 782 part = &infoPtr->part0; 783 783 else 784 784 #ifdef __WIN32OS2__ 785 785 { 786 786 if (nPart >= infoPtr->numParts) 787 788 787 return FALSE; 788 part = &infoPtr->parts[nPart]; 789 789 } 790 790 #else 791 791 part = &infoPtr->parts[nPart]; 792 792 #endif 793 793 if (!part) return FALSE; … … 801 801 if (style & SBT_OWNERDRAW) 802 802 { 803 803 part->text = text; 804 804 bRedraw = TRUE; 805 805 } else if(!text) … … 813 813 } else if(!part->text || strcmpW(part->text, text)) /* see if the new string differs from the existing string */ 814 814 { 815 815 if(part->text) COMCTL32_Free(part->text); 816 816 817 817 len = strlenW(text); 818 818 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR)); 819 819 strcpyW(part->text, text); 820 820 bRedraw = TRUE; 821 821 } … … 833 833 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam); 834 834 if (infoPtr->hwndToolTip) { 835 836 837 838 839 840 841 842 835 TTTOOLINFOA ti; 836 ti.cbSize = sizeof(TTTOOLINFOA); 837 ti.hwnd = hwnd; 838 ti.uId = (INT)wParam; 839 ti.hinst = 0; 840 ti.lpszText = (LPSTR)lParam; 841 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA, 842 0, (LPARAM)&ti); 843 843 } 844 844 … … 852 852 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam); 853 853 if (infoPtr->hwndToolTip) { 854 855 856 857 858 859 860 861 854 TTTOOLINFOW ti; 855 ti.cbSize = sizeof(TTTOOLINFOW); 856 ti.hwnd = hwnd; 857 ti.uId = (INT)wParam; 858 ti.hinst = 0; 859 ti.lpszText = (LPWSTR)lParam; 860 SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW, 861 0, (LPARAM)&ti); 862 862 } 863 863 … … 885 885 TRACE("(is simple: %d)\n", wParam); 886 886 if (infoPtr->simple == wParam) /* no need to change */ 887 887 return TRUE; 888 888 889 889 infoPtr->simple = (BOOL)wParam; … … 905 905 NONCLIENTMETRICSA nclm; 906 906 DWORD dwStyle; 907 RECT 908 int 909 HDC 907 RECT rect; 908 int width, len; 909 HDC hdc; 910 910 STATUSWINDOWINFO *infoPtr; 911 911 … … 951 951 952 952 if (IsWindowUnicode (hwnd)) { 953 954 955 956 957 958 953 infoPtr->bUnicode = TRUE; 954 if (lpCreate->lpszName && 955 (len = strlenW ((LPCWSTR)lpCreate->lpszName))) { 956 infoPtr->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR)); 957 strcpyW (infoPtr->parts[0].text, (LPCWSTR)lpCreate->lpszName); 958 } 959 959 } 960 960 else { 961 962 961 if (lpCreate->lpszName && 962 (len = strlen((LPCSTR)lpCreate->lpszName))) { 963 963 DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1, NULL, 0 ); 964 964 infoPtr->parts[0].text = COMCTL32_Alloc (lenW*sizeof(WCHAR)); 965 965 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1, 966 966 infoPtr->parts[0].text, lenW ); 967 967 } 968 968 } 969 969 … … 977 977 #endif 978 978 if ((hdc = GetDC (0))) { 979 980 981 982 983 984 985 986 979 TEXTMETRICA tm; 980 HFONT hOldFont; 981 982 hOldFont = SelectObject (hdc,infoPtr->hDefaultFont); 983 GetTextMetricsA(hdc, &tm); 984 infoPtr->textHeight = tm.tmHeight; 985 SelectObject (hdc, hOldFont); 986 ReleaseDC(0, hdc); 987 987 } 988 988 989 989 if (dwStyle & SBT_TOOLTIPS) { 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 990 infoPtr->hwndToolTip = 991 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0, 992 CW_USEDEFAULT, CW_USEDEFAULT, 993 CW_USEDEFAULT, CW_USEDEFAULT, 994 hwnd, 0, 995 GetWindowLongA (hwnd, GWL_HINSTANCE), NULL); 996 997 if (infoPtr->hwndToolTip) { 998 NMTOOLTIPSCREATED nmttc; 999 1000 nmttc.hdr.hwndFrom = hwnd; 1001 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID); 1002 nmttc.hdr.code = NM_TOOLTIPSCREATED; 1003 nmttc.hwndToolTips = infoPtr->hwndToolTip; 1004 1005 SendMessageA (lpCreate->hwndParent, WM_NOTIFY, 1006 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc); 1007 } 1008 1008 } 1009 1009 … … 1014 1014 infoPtr->height = infoPtr->textHeight + 4 + VERT_BORDER; 1015 1015 SetWindowPos(hwnd, 0, lpCreate->x, lpCreate->y - 1, 1016 1016 width, infoPtr->height, SWP_NOZORDER); 1017 1017 STATUSBAR_SetPartBounds (infoPtr, hwnd); 1018 1018 } … … 1025 1025 STATUSBAR_WMDestroy (STATUSWINDOWINFO *infoPtr, HWND hwnd) 1026 1026 { 1027 int 1027 int i; 1028 1028 1029 1029 TRACE("\n"); 1030 1030 for (i = 0; i < infoPtr->numParts; i++) { 1031 1032 1031 if (infoPtr->parts[i].text && !(infoPtr->parts[i].style & SBT_OWNERDRAW)) 1032 COMCTL32_Free (infoPtr->parts[i].text); 1033 1033 } 1034 1034 if (infoPtr->part0.text && !(infoPtr->part0.style & SBT_OWNERDRAW)) 1035 1035 COMCTL32_Free (infoPtr->part0.text); 1036 1036 COMCTL32_Free (infoPtr->parts); 1037 1037 1038 1038 /* delete default font */ 1039 1039 if (infoPtr->hDefaultFont) 1040 1040 DeleteObject (infoPtr->hDefaultFont); 1041 1041 1042 1042 /* delete tool tip control */ 1043 1043 if (infoPtr->hwndToolTip) 1044 1044 DestroyWindow (infoPtr->hwndToolTip); 1045 1045 1046 1046 COMCTL32_Free (infoPtr); … … 1074 1074 1075 1075 if (wParam > len) { 1076 1077 1078 1076 if (infoPtr->bUnicode) 1077 strcpyW ((LPWSTR)lParam, infoPtr->parts[0].text); 1078 else 1079 1079 WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1, 1080 1080 (LPSTR)lParam, len+1, NULL, NULL ); 1081 1081 return len; 1082 1082 } 1083 1083 … … 1090 1090 { 1091 1091 if (infoPtr->hwndToolTip) 1092 1093 1092 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, hwnd, 1093 WM_MOUSEMOVE, wParam, lParam); 1094 1094 return 0; 1095 1095 } … … 1100 1100 { 1101 1101 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) { 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1102 RECT rect; 1103 POINT pt; 1104 1105 GetClientRect (hwnd, &rect); 1106 1107 pt.x = (INT)LOWORD(lParam); 1108 pt.y = (INT)HIWORD(lParam); 1109 ScreenToClient (hwnd, &pt); 1110 1111 rect.left = rect.right - 13; 1112 rect.top += 2; 1113 1114 if (PtInRect (&rect, pt)) 1115 return HTBOTTOMRIGHT; 1116 1116 } 1117 1117 … … 1149 1149 STATUSBAR_Refresh (infoPtr, hwnd, hdc); 1150 1150 if (!wParam) 1151 1151 EndPaint (hwnd, &ps); 1152 1152 1153 1153 return 0; … … 1194 1194 TRACE("\n"); 1195 1195 if (infoPtr->numParts == 0) 1196 1196 return FALSE; 1197 1197 1198 1198 part = &infoPtr->parts[0]; … … 1202 1202 part->text = 0; 1203 1203 if (infoPtr->bUnicode) { 1204 1205 1206 1207 1204 if (lParam && (len = strlenW((LPCWSTR)lParam))) { 1205 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR)); 1206 strcpyW (part->text, (LPCWSTR)lParam); 1207 } 1208 1208 } 1209 1209 else { 1210 1210 if (lParam && (len = lstrlenA((LPCSTR)lParam))) { 1211 1211 DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lParam, -1, NULL, 0 ); 1212 1212 part->text = COMCTL32_Alloc (lenW*sizeof(WCHAR)); 1213 1213 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lParam, -1, part->text, lenW ); 1214 1214 } 1215 1215 } 1216 1216 … … 1240 1240 { 1241 1241 if (flags == SIZE_RESTORED) { 1242 1243 1244 1245 1246 1247 MoveWindow (hwnd, parent_rect.left, 1248 1249 1250 1242 /* width and height don't apply */ 1243 GetClientRect (infoPtr->hwndParent, &parent_rect); 1244 width = parent_rect.right - parent_rect.left; 1245 x = parent_rect.left; 1246 y = parent_rect.bottom - infoPtr->height; 1247 MoveWindow (hwnd, parent_rect.left, 1248 parent_rect.bottom - infoPtr->height, 1249 width, infoPtr->height, TRUE); 1250 STATUSBAR_SetPartBounds (infoPtr, hwnd); 1251 1251 } 1252 1252 return 0; /* FIXME: ok to return here ? */ 1253 1253 } 1254 1254 … … 1283 1283 1284 1284 switch (msg) { 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 case SB_SETPARTS: 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1285 case SB_GETBORDERS: 1286 return STATUSBAR_GetBorders (lParam); 1287 1288 case SB_GETICON: 1289 return STATUSBAR_GetIcon (infoPtr, hwnd, wParam); 1290 1291 case SB_GETPARTS: 1292 return STATUSBAR_GetParts (infoPtr, hwnd, wParam, lParam); 1293 1294 case SB_GETRECT: 1295 return STATUSBAR_GetRect (infoPtr, hwnd, wParam, lParam); 1296 1297 case SB_GETTEXTA: 1298 return STATUSBAR_GetTextA (infoPtr, hwnd, wParam, lParam); 1299 1300 case SB_GETTEXTW: 1301 return STATUSBAR_GetTextW (infoPtr, hwnd, wParam, lParam); 1302 1303 case SB_GETTEXTLENGTHA: 1304 case SB_GETTEXTLENGTHW: 1305 return STATUSBAR_GetTextLength (infoPtr, hwnd, wParam); 1306 1307 case SB_GETTIPTEXTA: 1308 return STATUSBAR_GetTipTextA (infoPtr, hwnd, wParam, lParam); 1309 1310 case SB_GETTIPTEXTW: 1311 return STATUSBAR_GetTipTextW (infoPtr, hwnd, wParam, lParam); 1312 1313 case SB_GETUNICODEFORMAT: 1314 return STATUSBAR_GetUnicodeFormat (infoPtr, hwnd); 1315 1316 case SB_ISSIMPLE: 1317 return STATUSBAR_IsSimple (infoPtr, hwnd); 1318 1319 case SB_SETBKCOLOR: 1320 return STATUSBAR_SetBkColor (infoPtr, hwnd, wParam, lParam); 1321 1322 case SB_SETICON: 1323 return STATUSBAR_SetIcon (infoPtr, hwnd, wParam, lParam); 1324 1325 case SB_SETMINHEIGHT: 1326 return STATUSBAR_SetMinHeight (infoPtr, hwnd, wParam, lParam); 1327 1328 case SB_SETPARTS: 1329 return STATUSBAR_SetParts (infoPtr, hwnd, wParam, lParam); 1330 1331 case SB_SETTEXTA: 1332 return STATUSBAR_SetTextA (infoPtr, hwnd, wParam, lParam); 1333 1334 case SB_SETTEXTW: 1335 return STATUSBAR_SetTextW (infoPtr, hwnd, wParam, lParam); 1336 1337 case SB_SETTIPTEXTA: 1338 return STATUSBAR_SetTipTextA (infoPtr, hwnd, wParam, lParam); 1339 1340 case SB_SETTIPTEXTW: 1341 return STATUSBAR_SetTipTextW (infoPtr, hwnd, wParam, lParam); 1342 1343 case SB_SETUNICODEFORMAT: 1344 return STATUSBAR_SetUnicodeFormat (infoPtr, hwnd, wParam); 1345 1346 case SB_SIMPLE: 1347 return STATUSBAR_Simple (infoPtr, hwnd, wParam, lParam); 1348 1349 1350 case WM_CREATE: 1351 return STATUSBAR_WMCreate (hwnd, wParam, lParam); 1352 1353 case WM_DESTROY: 1354 return STATUSBAR_WMDestroy (infoPtr, hwnd); 1355 1356 case WM_GETFONT: 1357 1357 return STATUSBAR_WMGetFont (infoPtr, hwnd); 1358 1358 1359 1359 case WM_GETTEXT: 1360 1360 return STATUSBAR_WMGetText (infoPtr, hwnd, wParam, lParam); 1361 1361 1362 1363 1364 1365 1362 case WM_GETTEXTLENGTH: 1363 return STATUSBAR_GetTextLength (infoPtr, hwnd, 0); 1364 1365 case WM_LBUTTONDBLCLK: 1366 1366 return STATUSBAR_SendNotify (hwnd, NM_DBLCLK); 1367 1367 1368 1369 1370 1371 1368 case WM_LBUTTONUP: 1369 return STATUSBAR_SendNotify (hwnd, NM_CLICK); 1370 1371 case WM_MOUSEMOVE: 1372 1372 return STATUSBAR_WMMouseMove (infoPtr, hwnd, wParam, lParam); 1373 1373 1374 1374 case WM_NCHITTEST: 1375 1375 return STATUSBAR_WMNCHitTest (hwnd, wParam, lParam); 1376 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1377 case WM_NCLBUTTONDOWN: 1378 return STATUSBAR_WMNCLButtonDown (hwnd, wParam, lParam); 1379 1380 case WM_NCLBUTTONUP: 1381 return STATUSBAR_WMNCLButtonUp (hwnd, wParam, lParam); 1382 1383 case WM_PAINT: 1384 return STATUSBAR_WMPaint (infoPtr, hwnd, wParam); 1385 1386 case WM_RBUTTONDBLCLK: 1387 return STATUSBAR_SendNotify (hwnd, NM_RDBLCLK); 1388 1389 case WM_RBUTTONUP: 1390 return STATUSBAR_SendNotify (hwnd, NM_RCLICK); 1391 1392 case WM_SETFONT: 1393 return STATUSBAR_WMSetFont (infoPtr, hwnd, wParam, lParam); 1394 1395 case WM_SETTEXT: 1396 return STATUSBAR_WMSetText (infoPtr, hwnd, wParam, lParam); 1397 1398 case WM_SIZE: 1399 return STATUSBAR_WMSize (infoPtr, hwnd, wParam, lParam); 1400 1401 default: 1402 if (msg >= WM_USER) 1403 ERR("unknown msg %04x wp=%04x lp=%08lx\n", 1404 msg, wParam, lParam); 1405 1405 #ifdef __WIN32OS2__ 1406 1406 return defComCtl32ProcA (hwnd, msg, wParam, lParam); 1407 1407 #else 1408 1408 return DefWindowProcA (hwnd, msg, wParam, lParam); 1409 1409 #endif 1410 1410 } … … 1432 1432 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); 1433 1433 wndClass.lpszClassName = STATUSCLASSNAMEA; 1434 1434 1435 1435 RegisterClassA (&wndClass); 1436 1436 } -
trunk/src/comctl32/tab.c
r6705 r6709 36 36 LPARAM lParam; 37 37 RECT rect; /* bounding rectangle of the item relative to the 38 * leftmost item (the leftmost item, 0, would have a 39 * "left" member of 0 in this rectangle) 40 * 38 * leftmost item (the leftmost item, 0, would have a 39 * "left" member of 0 in this rectangle) 40 * 41 41 * additionally the top member hold the row number 42 42 * and bottom is unused and should be 0 */ … … 49 49 #endif 50 50 UINT uNumItem; /* number of tab items */ 51 UINT uNumRows; 51 UINT uNumRows; /* number of tab rows */ 52 52 INT tabHeight; /* height of the tab row */ 53 53 INT tabWidth; /* width of tabs */ … … 57 57 HWND hwndToolTip; /* handle to tab's tooltip */ 58 58 INT leftmostVisible; /* Used for scrolling, this member contains 59 59 * the index of the first visible item */ 60 60 INT iSelected; /* the currently selected item */ 61 61 INT iHotTracked; /* the highlighted item under the mouse */ … … 63 63 TAB_ITEM* items; /* pointer to an array of TAB_ITEM's */ 64 64 BOOL DoRedraw; /* flag for redrawing when tab contents is changed*/ 65 BOOL needsScrolling; /* TRUE if the size of the tabs is greater than 66 67 BOOL fSizeSet;/* was the size of the tabs explicitly set? */65 BOOL needsScrolling; /* TRUE if the size of the tabs is greater than 66 * the size of the control */ 67 BOOL fSizeSet; /* was the size of the tabs explicitly set? */ 68 68 BOOL bUnicode; /* Unicode control? */ 69 69 HWND hwndUpDown; /* Updown control used for scrolling */ … … 81 81 #define CONTROL_BORDER_SIZEX 2 82 82 #define CONTROL_BORDER_SIZEY 2 83 #define BUTTON_SPACINGX 4 83 #define BUTTON_SPACINGX 4 84 84 #define BUTTON_SPACINGY 4 85 85 #define FLAT_BTN_SPACINGX 8 … … 137 137 { 138 138 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 139 139 140 140 return infoPtr->iSelected; 141 141 } … … 145 145 { 146 146 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 147 147 148 148 return infoPtr->uFocus; 149 149 } … … 164 164 INT iItem = (INT)wParam; 165 165 INT prevItem; 166 166 167 167 prevItem = -1; 168 168 if ((iItem >= 0) && (iItem < infoPtr->uNumItem)) { … … 180 180 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 181 181 INT iItem=(INT) wParam; 182 182 183 183 if ((iItem < 0) || (iItem >= infoPtr->uNumItem)) return 0; 184 184 185 185 if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BUTTONS) { 186 186 FIXME("Should set input focus\n"); 187 } else { 187 } else { 188 188 int oldFocus = infoPtr->uFocus; 189 189 if (infoPtr->iSelected != iItem || infoPtr->uFocus == -1 ) { … … 232 232 RECT tmpItemRect,clientRect; 233 233 LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE); 234 234 235 235 /* Perform a sanity check and a trivial visibility check. */ 236 236 if ( (infoPtr->uNumItem <= 0) || … … 245 245 if (itemRect == NULL) 246 246 itemRect = &tmpItemRect; 247 247 248 248 /* Retrieve the unmodified item rect. */ 249 249 *itemRect = infoPtr->items[itemIndex].rect; … … 280 280 else if(!(lStyle & TCS_VERTICAL) && !(lStyle & TCS_BOTTOM)) /* not TCS_BOTTOM and not TCS_VERTICAL */ 281 281 { 282 itemRect->bottom = clientRect.top + 282 itemRect->bottom = clientRect.top + 283 283 infoPtr->tabHeight + 284 284 itemRect->top * (infoPtr->tabHeight - 2) + 285 285 ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : 0); 286 itemRect->top = clientRect.top + 286 itemRect->top = clientRect.top + 287 287 SELECTED_TAB_OFFSET + 288 288 itemRect->top * (infoPtr->tabHeight - 2) + … … 291 291 292 292 /* 293 * "scroll" it to make sure the item at the very left of the 293 * "scroll" it to make sure the item at the very left of the 294 294 * tab control is the leftmost visible tab. 295 295 */ … … 297 297 { 298 298 OffsetRect(itemRect, 299 300 299 0, 300 -(clientRect.bottom - infoPtr->items[infoPtr->leftmostVisible].rect.bottom)); 301 301 302 302 /* … … 305 305 */ 306 306 OffsetRect(itemRect, 307 308 307 0, 308 -SELECTED_TAB_OFFSET); 309 309 310 310 } else 311 311 { 312 312 OffsetRect(itemRect, 313 -infoPtr->items[infoPtr->leftmostVisible].rect.left, 314 313 -infoPtr->items[infoPtr->leftmostVisible].rect.left, 314 0); 315 315 316 316 /* … … 319 319 */ 320 320 OffsetRect(itemRect, 321 322 321 SELECTED_TAB_OFFSET, 322 0); 323 323 } 324 324 … … 336 336 /* If it also a bit higher. */ 337 337 if ((lStyle & TCS_BOTTOM) && !(lStyle & TCS_VERTICAL)) 338 { 338 { 339 339 selectedRect->top -= 2; /* the border is thicker on the bottom */ 340 340 selectedRect->bottom += SELECTED_TAB_OFFSET; … … 362 362 static BOOL TAB_GetItemRect(HWND hwnd, WPARAM wParam, LPARAM lParam) 363 363 { 364 return TAB_InternalGetItemRect(hwnd, TAB_GetInfoPtr(hwnd), (INT)wParam, 364 return TAB_InternalGetItemRect(hwnd, TAB_GetInfoPtr(hwnd), (INT)wParam, 365 365 (LPRECT)lParam, (LPRECT)NULL); 366 366 } … … 372 372 */ 373 373 static LRESULT TAB_KeyUp( 374 HWND hwnd, 374 HWND hwnd, 375 375 WPARAM keyCode) 376 376 { … … 387 387 break; 388 388 } 389 389 390 390 /* 391 391 * If we changed to a valid item, change the selection … … 416 416 */ 417 417 static LRESULT TAB_FocusChanging( 418 HWND hwnd, 419 UINT uMsg, 420 WPARAM wParam, 418 HWND hwnd, 419 UINT uMsg, 420 WPARAM wParam, 421 421 LPARAM lParam) 422 422 { … … 429 429 */ 430 430 isVisible = TAB_InternalGetItemRect(hwnd, 431 432 433 434 435 431 infoPtr, 432 infoPtr->uFocus, 433 NULL, 434 &selectedRect); 435 436 436 /* 437 437 * If the rectangle is not completely invisible, invalidate that … … 451 451 static HWND TAB_InternalHitTest ( 452 452 HWND hwnd, 453 TAB_INFO* infoPtr, 454 POINT pt, 453 TAB_INFO* infoPtr, 454 POINT pt, 455 455 UINT* flags) 456 456 457 457 { 458 458 RECT rect; 459 int iCount; 460 459 int iCount; 460 461 461 for (iCount = 0; iCount < infoPtr->uNumItem; iCount++) 462 462 { … … 479 479 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 480 480 LPTCHITTESTINFO lptest = (LPTCHITTESTINFO) lParam; 481 481 482 482 return TAB_InternalHitTest (hwnd, infoPtr, lptest->pt, &lptest->flags); 483 483 } … … 521 521 if (infoPtr->hwndToolTip) 522 522 TAB_RelayEvent (infoPtr->hwndToolTip, hwnd, 523 523 WM_LBUTTONDOWN, wParam, lParam); 524 524 525 525 if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_FOCUSONBUTTONDOWN ) { … … 529 529 if (infoPtr->hwndToolTip) 530 530 TAB_RelayEvent (infoPtr->hwndToolTip, hwnd, 531 532 531 WM_LBUTTONDOWN, wParam, lParam); 532 533 533 pt.x = (INT)LOWORD(lParam); 534 534 pt.y = (INT)HIWORD(lParam); 535 535 536 536 newItem = TAB_InternalHitTest (hwnd, infoPtr, pt, &dummy); 537 537 538 538 TRACE("On Tab, item %d\n", newItem); 539 539 … … 619 619 ** overlaps. Note also that the case where the cursor stayed within our 620 620 ** window but has moved off the hot-tracked tab will be handled by the 621 ** WM_MOUSEMOVE event. 621 ** WM_MOUSEMOVE event. 622 622 */ 623 623 if (!GetCursorPos(&pt) || WindowFromPoint(pt) != hwnd) … … 721 721 if (item >= 0) 722 722 { 723 723 /* Mark new hot-tracked to be redrawn to look highlighted */ 724 724 if (out_redrawEnter != NULL) 725 725 *out_redrawEnter = item; … … 743 743 if (infoPtr->hwndToolTip) 744 744 TAB_RelayEvent (infoPtr->hwndToolTip, hwnd, 745 745 WM_LBUTTONDOWN, wParam, lParam); 746 746 747 747 /* Determine which tab to highlight. Redraw tabs which change highlight … … 764 764 */ 765 765 static LRESULT TAB_AdjustRect( 766 HWND hwnd, 767 WPARAM fLarger, 766 HWND hwnd, 767 WPARAM fLarger, 768 768 LPRECT prc) 769 769 { … … 845 845 */ 846 846 static LRESULT TAB_OnHScroll( 847 HWND hwnd, 847 HWND hwnd, 848 848 int nScrollCode, 849 849 int nPos, … … 871 871 * TAB_SetupScrolling 872 872 * 873 * This method will check the current scrolling state and make sure the 873 * This method will check the current scrolling state and make sure the 874 874 * scrolling control is displayed (or not). 875 875 */ … … 930 930 { 931 931 infoPtr->hwndUpDown = CreateWindowA("msctls_updown32", 932 933 934 935 936 937 938 (HMENU)NULL, 939 (HINSTANCE)NULL, 940 NULL); 932 "", 933 WS_VISIBLE | WS_CHILD | UDS_HORZ, 934 controlPos.left, controlPos.top, 935 controlPos.right - controlPos.left, 936 controlPos.bottom - controlPos.top, 937 hwnd, 938 (HMENU)NULL, 939 (HINSTANCE)NULL, 940 NULL); 941 941 } 942 942 else 943 943 { 944 SetWindowPos(infoPtr->hwndUpDown, 945 946 947 948 949 SWP_SHOWWINDOW | SWP_NOZORDER); 944 SetWindowPos(infoPtr->hwndUpDown, 945 (HWND)NULL, 946 controlPos.left, controlPos.top, 947 controlPos.right - controlPos.left, 948 controlPos.bottom - controlPos.top, 949 SWP_SHOWWINDOW | SWP_NOZORDER); 950 950 } 951 951 … … 1010 1010 * a font. 1011 1011 */ 1012 hdc = GetDC(hwnd); 1013 1012 hdc = GetDC(hwnd); 1013 1014 1014 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT); 1015 1015 hOldFont = SelectObject (hdc, hFont); … … 1022 1022 1023 1023 /* if TCS_VERTICAL then swap the height and width so this code places the 1024 tabs along the top of the rectangle and we can just rotate them after 1024 tabs along the top of the rectangle and we can just rotate them after 1025 1025 rather than duplicate all of the below code */ 1026 1026 if(lStyle & TCS_VERTICAL) … … 1054 1054 1055 1055 /* 1056 * Make sure there is enough space for the letters + icon + growing the 1057 * selected item + extra space for the selected item. 1056 * Make sure there is enough space for the letters + icon + growing the 1057 * selected item + extra space for the selected item. 1058 1058 */ 1059 1059 infoPtr->tabHeight = item_height + 2 * VERTICAL_ITEM_PADDING + … … 1085 1085 * for button style tabs */ 1086 1086 if (lStyle & TCS_BUTTONS) 1087 1087 size.cx = max(size.cx, 2 * (infoPtr->tabHeight - 2)); 1088 1088 1089 1089 /* Add the icon width */ … … 1095 1095 1096 1096 infoPtr->items[curItem].rect.right = infoPtr->items[curItem].rect.left + 1097 size.cx + icon_width + 1097 size.cx + icon_width + 1098 1098 num * HORIZONTAL_ITEM_PADDING; 1099 1099 } … … 1114 1114 infoPtr->items[curItem].rect.left; 1115 1115 1116 1116 infoPtr->items[curItem].rect.left = 0; 1117 1117 curItemRowCount++; 1118 1118 } … … 1122 1122 1123 1123 TRACE("TextSize: %li\n", size.cx); 1124 TRACE("Rect: T %i, L %i, B %i, R %i\n", 1125 1126 1127 1128 infoPtr->items[curItem].rect.right); 1124 TRACE("Rect: T %i, L %i, B %i, R %i\n", 1125 infoPtr->items[curItem].rect.top, 1126 infoPtr->items[curItem].rect.left, 1127 infoPtr->items[curItem].rect.bottom, 1128 infoPtr->items[curItem].rect.right); 1129 1129 1130 1130 /* … … 1152 1152 /* Don't need scrolling, then update infoPtr->leftmostVisible */ 1153 1153 if(!infoPtr->needsScrolling) 1154 infoPtr->leftmostVisible = 0; 1154 infoPtr->leftmostVisible = 0; 1155 1155 1156 1156 TAB_SetupScrolling(hwnd, infoPtr, &clientRect); … … 1193 1193 1194 1194 /* shift the item to the left side of the clientRect */ 1195 infoPtr->items[iItm].rect.right -= 1195 infoPtr->items[iItm].rect.right -= 1196 1196 infoPtr->items[iItm].rect.left; 1197 1197 infoPtr->items[iItm].rect.left = 0; … … 1202 1202 infoPtr->items[iItm].rect.top = iRow; 1203 1203 if (lStyle & TCS_BUTTONS) 1204 1204 { 1205 1205 curItemLeftPos = infoPtr->items[iItm].rect.right + 1; 1206 1206 if (lStyle & TCS_FLATBUTTONS) 1207 1208 1207 curItemLeftPos += FLAT_BTN_SPACINGX; 1208 } 1209 1209 else 1210 1210 curItemLeftPos = infoPtr->items[iItm].rect.right; 1211 1211 } 1212 1212 1213 1213 /* 1214 1214 * Justify the rows … … 1217 1217 while(iIndexStart < infoPtr->uNumItem) 1218 1218 { 1219 /* 1219 /* 1220 1220 * find the indexs of the row 1221 1221 */ 1222 1222 /* find the first item on the next row */ 1223 1223 for (iIndexEnd=iIndexStart; 1224 (iIndexEnd < infoPtr->uNumItem) && 1225 1224 (iIndexEnd < infoPtr->uNumItem) && 1225 (infoPtr->items[iIndexEnd].rect.top == 1226 1226 infoPtr->items[iIndexStart].rect.top) ; 1227 1227 iIndexEnd++) 1228 1228 /* intentionaly blank */; 1229 1229 1230 /* 1230 /* 1231 1231 * we need to justify these tabs so they fill the whole given 1232 1232 * client area … … 1246 1246 widthDiff = widthDiff / iCount; 1247 1247 /* add widthDiff/iCount, or extra space/items on row, to each item on this row */ 1248 for (iIndex=iIndexStart,iCount=0; iIndex < iIndexEnd; 1248 for (iIndex=iIndexStart,iCount=0; iIndex < iIndexEnd; 1249 1249 iIndex++,iCount++) 1250 1250 { … … 1297 1297 * This method is used to draw the interior (text and icon) of a single tab 1298 1298 * into the tab control. 1299 */ 1299 */ 1300 1300 static void 1301 1301 TAB_DrawItemInterior … … 1390 1390 id = GetWindowLongA( hwnd, GWL_ID ); 1391 1391 1392 /* 1392 /* 1393 1393 * put together the DRAWITEMSTRUCT 1394 1394 */ 1395 dis.CtlType = ODT_TAB; 1396 dis.CtlID = id; 1397 dis.itemID = iItem; 1398 dis.itemAction = ODA_DRAWENTIRE; 1395 dis.CtlType = ODT_TAB; 1396 dis.CtlID = id; 1397 dis.itemID = iItem; 1398 dis.itemAction = ODA_DRAWENTIRE; 1399 1399 if ( iItem == infoPtr->iSelected ) 1400 dis.itemState = ODS_SELECTED; 1401 else 1402 dis.itemState = 0; 1403 dis.hwndItem = hwnd; 1404 dis.hDC = hdc; 1405 dis.rcItem = *drawRect; 1400 dis.itemState = ODS_SELECTED; 1401 else 1402 dis.itemState = 0; 1403 dis.hwndItem = hwnd; /* */ 1404 dis.hDC = hdc; 1405 dis.rcItem = *drawRect; /* */ 1406 1406 dis.itemData = infoPtr->items[iItem].lParam; 1407 1407 … … 1538 1538 if(lStyle & TCS_VERTICAL) 1539 1539 { 1540 if (!GetObjectA((infoPtr->hFont) ? 1540 if (!GetObjectA((infoPtr->hFont) ? 1541 1541 infoPtr->hFont : GetStockObject(SYSTEM_FONT), 1542 1542 sizeof(LOGFONTA),&logfont)) … … 1545 1545 1546 1546 lstrcpyA(logfont.lfFaceName, "Arial"); 1547 logfont.lfHeight = -MulDiv(iPointSize, GetDeviceCaps(hdc, LOGPIXELSY), 1547 logfont.lfHeight = -MulDiv(iPointSize, GetDeviceCaps(hdc, LOGPIXELSY), 1548 1548 72); 1549 1549 logfont.lfWeight = FW_NORMAL; … … 1604 1604 * 1605 1605 * This method is used to draw a single tab into the tab control. 1606 */ 1606 */ 1607 1607 static void TAB_DrawItem( 1608 HWND hwnd, 1609 HDC hdc, 1608 HWND hwnd, 1609 HDC hdc, 1610 1610 INT iItem) 1611 1611 { … … 1621 1621 */ 1622 1622 isVisible = TAB_InternalGetItemRect(hwnd, 1623 1624 1625 1626 1623 infoPtr, 1624 iItem, 1625 &itemRect, 1626 &selectedRect); 1627 1627 1628 1628 if (isVisible) 1629 1629 { 1630 HBRUSH hbr = CreateSolidBrush (GetSysColor(COLOR_BTNFACE)); 1630 HBRUSH hbr = CreateSolidBrush (GetSysColor(COLOR_BTNFACE)); 1631 1631 HPEN hwPen = GetSysColorPen (COLOR_3DHILIGHT); 1632 1632 HPEN hbPen = GetSysColorPen (COLOR_3DDKSHADOW); … … 1645 1645 /* Separators between flat buttons */ 1646 1646 /* FIXME: test and correct this if necessary for TCS_FLATBUTTONS style */ 1647 if (lStyle & TCS_FLATBUTTONS) 1647 if (lStyle & TCS_FLATBUTTONS) 1648 1648 { 1649 1649 int x = r.right + FLAT_BTN_SPACINGX - 2; … … 1669 1669 /* Background color */ 1670 1670 if (!((lStyle & TCS_OWNERDRAWFIXED) && infoPtr->fSizeSet)) 1671 1671 { 1672 1672 COLORREF bk = GetSysColor(COLOR_3DHILIGHT); 1673 1673 DeleteObject(hbr); … … 1685 1685 1686 1686 deleteBrush = FALSE; 1687 1687 } 1688 1688 1689 1689 /* Erase the background */ … … 1704 1704 LineTo (hdc, r.right, r.bottom); 1705 1705 LineTo (hdc, r.right, r.top + 1); 1706 1706 1707 1707 /* shadow */ 1708 1708 SelectObject(hdc, hbPen); … … 1721 1721 FillRect(hdc, &r, hbr); 1722 1722 1723 1724 1723 if (!(lStyle & TCS_FLATBUTTONS)) 1724 { 1725 1725 /* highlight */ 1726 1726 MoveToEx (hdc, r.left, r.bottom, NULL); 1727 1727 LineTo (hdc, r.left, r.top); 1728 1728 LineTo (hdc, r.right, r.top); 1729 1729 1730 1730 /* shadow */ 1731 1731 SelectObject(hdc, hbPen); … … 1738 1738 LineTo (hdc, r.right - 1, r.bottom - 1); 1739 1739 LineTo (hdc, r.left + 1, r.bottom - 1); 1740 1740 } 1741 1741 } 1742 1742 } … … 1745 1745 /* Background color */ 1746 1746 DeleteObject(hbr); 1747 hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); 1747 hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); 1748 1748 1749 1749 /* We draw a rectangle of different sizes depending on the selection … … 1756 1756 /* 1757 1757 * Erase the background. 1758 * This is necessary when drawing the selected item since it is larger 1759 * than the others, it might overlap with stuff already drawn by the 1758 * This is necessary when drawing the selected item since it is larger 1759 * than the others, it might overlap with stuff already drawn by the 1760 1760 * other tabs 1761 */ 1761 */ 1762 1762 FillRect(hdc, &r, hbr); 1763 1763 … … 1770 1770 r.right--; 1771 1771 r.bottom--; 1772 1772 1773 1773 holdPen = SelectObject (hdc, hwPen); 1774 1774 if(lStyle & TCS_VERTICAL) … … 1859 1859 } 1860 1860 } 1861 1861 1862 1862 /* This modifies r to be the text rectangle. */ 1863 1863 { … … 1868 1868 /* Draw the focus rectangle */ 1869 1869 if (((lStyle & TCS_FOCUSNEVER) == 0) && 1870 1871 1870 (GetFocus() == hwnd) && 1871 (iItem == infoPtr->uFocus) ) 1872 1872 { 1873 1873 r = itemRect; … … 1888 1888 * This method is used to draw the raised border around the tab control 1889 1889 * "content" area. 1890 */ 1890 */ 1891 1891 static void TAB_DrawBorder (HWND hwnd, HDC hdc) 1892 1892 { … … 1957 1957 * 1958 1958 * This method repaints the tab control.. 1959 */ 1959 */ 1960 1960 static void TAB_Refresh (HWND hwnd, HDC hdc) 1961 1961 { … … 1971 1971 if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BUTTONS) 1972 1972 { 1973 for (i = 0; i < infoPtr->uNumItem; i++) 1973 for (i = 0; i < infoPtr->uNumItem; i++) 1974 1974 TAB_DrawItem (hwnd, hdc, i); 1975 1975 } … … 1977 1977 { 1978 1978 /* Draw all the non selected item first */ 1979 for (i = 0; i < infoPtr->uNumItem; i++) 1979 for (i = 0; i < infoPtr->uNumItem; i++) 1980 1980 { 1981 1981 if (i != infoPtr->iSelected) 1982 1982 TAB_DrawItem (hwnd, hdc, i); 1983 1983 } 1984 1984 … … 2011 2011 { 2012 2012 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 2013 2013 2014 2014 infoPtr->DoRedraw=(BOOL) wParam; 2015 2015 return 0; … … 2017 2017 2018 2018 static LRESULT TAB_EraseBackground( 2019 HWND hwnd, 2019 HWND hwnd, 2020 2020 HDC givenDC) 2021 2021 { … … 2207 2207 HDC hdc; 2208 2208 PAINTSTRUCT ps; 2209 2209 2210 2210 hdc = wParam== 0 ? BeginPaint (hwnd, &ps) : (HDC)wParam; 2211 2211 TAB_Refresh (hwnd, hdc); 2212 2212 2213 2213 if(!wParam) 2214 2214 EndPaint (hwnd, &ps); … … 2219 2219 static LRESULT 2220 2220 TAB_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) 2221 { 2221 { 2222 2222 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 2223 2223 TCITEMA *pti; 2224 2224 INT iItem; 2225 2225 RECT rect; 2226 2226 2227 2227 GetClientRect (hwnd, &rect); 2228 2228 TRACE("Rect: %x T %i, L %i, B %i, R %i\n", hwnd, 2229 rect.top, rect.left, rect.bottom, rect.right); 2230 2229 rect.top, rect.left, rect.bottom, rect.right); 2230 2231 2231 pti = (TCITEMA *)lParam; 2232 2232 iItem = (INT)wParam; 2233 2233 2234 2234 if (iItem < 0) return -1; 2235 2235 if (iItem > infoPtr->uNumItem) 2236 2236 iItem = infoPtr->uNumItem; 2237 2237 2238 2238 if (infoPtr->uNumItem == 0) { 2239 2239 infoPtr->items = COMCTL32_Alloc (sizeof (TAB_ITEM)); … … 2243 2243 else { 2244 2244 TAB_ITEM *oldItems = infoPtr->items; 2245 2245 2246 2246 infoPtr->uNumItem++; 2247 2247 infoPtr->items = COMCTL32_Alloc (sizeof (TAB_ITEM) * infoPtr->uNumItem); 2248 2248 2249 2249 /* pre insert copy */ 2250 2250 if (iItem > 0) { 2251 2251 memcpy (&infoPtr->items[0], &oldItems[0], 2252 2253 } 2254 2252 iItem * sizeof(TAB_ITEM)); 2253 } 2254 2255 2255 /* post insert copy */ 2256 2256 if (iItem < infoPtr->uNumItem - 1) { 2257 2257 memcpy (&infoPtr->items[iItem+1], &oldItems[iItem], 2258 2259 2258 (infoPtr->uNumItem - iItem - 1) * sizeof(TAB_ITEM)); 2259 2260 2260 } 2261 2261 … … 2265 2265 COMCTL32_Free (oldItems); 2266 2266 } 2267 2267 2268 2268 infoPtr->items[iItem].mask = pti->mask; 2269 2269 if (pti->mask & TCIF_TEXT) … … 2272 2272 if (pti->mask & TCIF_IMAGE) 2273 2273 infoPtr->items[iItem].iImage = pti->iImage; 2274 2274 2275 2275 if (pti->mask & TCIF_PARAM) 2276 2276 infoPtr->items[iItem].lParam = pti->lParam; 2277 2277 2278 2278 TAB_SetItemBounds(hwnd); 2279 2279 TAB_InvalidateTabArea(hwnd, infoPtr); 2280 2280 2281 2281 TRACE("[%04x]: added item %d '%s'\n", 2282 2282 hwnd, iItem, debugstr_w(infoPtr->items[iItem].pszText)); 2283 2283 2284 2284 return iItem; … … 2319 2319 if (iItem > 0) { 2320 2320 memcpy (&infoPtr->items[0], &oldItems[0], 2321 2321 iItem * sizeof(TAB_ITEM)); 2322 2322 } 2323 2323 … … 2325 2325 if (iItem < infoPtr->uNumItem - 1) { 2326 2326 memcpy (&infoPtr->items[iItem+1], &oldItems[iItem], 2327 2328 2329 } 2330 2327 (infoPtr->uNumItem - iItem - 1) * sizeof(TAB_ITEM)); 2328 2329 } 2330 2331 2331 if (iItem <= infoPtr->iSelected) 2332 2332 infoPtr->iSelected++; … … 2341 2341 if (pti->mask & TCIF_IMAGE) 2342 2342 infoPtr->items[iItem].iImage = pti->iImage; 2343 2343 2344 2344 if (pti->mask & TCIF_PARAM) 2345 2345 infoPtr->items[iItem].lParam = pti->lParam; 2346 2346 2347 2347 TAB_SetItemBounds(hwnd); 2348 2348 TAB_InvalidateTabArea(hwnd, infoPtr); 2349 2349 2350 2350 TRACE("[%04x]: added item %d '%s'\n", 2351 2351 hwnd, iItem, debugstr_w(infoPtr->items[iItem].pszText)); 2352 2352 2353 2353 return iItem; … … 2355 2355 2356 2356 2357 static LRESULT 2357 static LRESULT 2358 2358 TAB_SetItemSize (HWND hwnd, WPARAM wParam, LPARAM lParam) 2359 2359 { … … 2373 2373 } 2374 2374 2375 static LRESULT 2375 static LRESULT 2376 2376 TAB_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) 2377 2377 { 2378 2378 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 2379 TCITEMA *tabItem; 2379 TCITEMA *tabItem; 2380 2380 TAB_ITEM *wineItem; 2381 2381 INT iItem; … … 2395 2395 wineItem->lParam = tabItem->lParam; 2396 2396 2397 if (tabItem->mask & TCIF_RTLREADING) 2397 if (tabItem->mask & TCIF_RTLREADING) 2398 2398 FIXME("TCIF_RTLREADING\n"); 2399 2399 2400 if (tabItem->mask & TCIF_STATE) 2400 if (tabItem->mask & TCIF_STATE) 2401 2401 wineItem->dwState = tabItem->dwState; 2402 2402 … … 2451 2451 2452 2452 2453 static LRESULT 2453 static LRESULT 2454 2454 TAB_GetItemCount (HWND hwnd, WPARAM wParam, LPARAM lParam) 2455 2455 { … … 2460 2460 2461 2461 2462 static LRESULT 2462 static LRESULT 2463 2463 TAB_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) 2464 2464 { … … 2476 2476 wineItem = &infoPtr->items[iItem]; 2477 2477 2478 if (tabItem->mask & TCIF_IMAGE) 2478 if (tabItem->mask & TCIF_IMAGE) 2479 2479 tabItem->iImage = wineItem->iImage; 2480 2480 2481 if (tabItem->mask & TCIF_PARAM) 2481 if (tabItem->mask & TCIF_PARAM) 2482 2482 tabItem->lParam = wineItem->lParam; 2483 2483 2484 if (tabItem->mask & TCIF_RTLREADING) 2484 if (tabItem->mask & TCIF_RTLREADING) 2485 2485 FIXME("TCIF_RTLREADING\n"); 2486 2486 2487 if (tabItem->mask & TCIF_STATE) 2487 if (tabItem->mask & TCIF_STATE) 2488 2488 tabItem->dwState = wineItem->dwState; 2489 2489 2490 if (tabItem->mask & TCIF_TEXT) 2490 if (tabItem->mask & TCIF_TEXT) 2491 2491 Str_GetPtrWtoA (wineItem->pszText, tabItem->pszText, tabItem->cchTextMax); 2492 2492 … … 2495 2495 2496 2496 2497 static LRESULT 2497 static LRESULT 2498 2498 TAB_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam) 2499 2499 { … … 2530 2530 2531 2531 2532 static LRESULT 2532 static LRESULT 2533 2533 TAB_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam) 2534 2534 { … … 2540 2540 { 2541 2541 TAB_ITEM *oldItems = infoPtr->items; 2542 2542 2543 2543 infoPtr->uNumItem--; 2544 2544 infoPtr->items = COMCTL32_Alloc(sizeof (TAB_ITEM) * infoPtr->uNumItem); 2545 2546 if (iItem > 0) 2545 2546 if (iItem > 0) 2547 2547 memcpy(&infoPtr->items[0], &oldItems[0], iItem * sizeof(TAB_ITEM)); 2548 2549 if (iItem < infoPtr->uNumItem) 2548 2549 if (iItem < infoPtr->uNumItem) 2550 2550 memcpy(&infoPtr->items[iItem], &oldItems[iItem + 1], 2551 2551 (infoPtr->uNumItem - iItem) * sizeof(TAB_ITEM)); 2552 2552 2553 2553 COMCTL32_Free(oldItems); 2554 2554 … … 2556 2556 if ((iItem == infoPtr->iSelected) && (iItem > 0)) 2557 2557 infoPtr->iSelected--; 2558 2558 2559 2559 if (iItem < infoPtr->iSelected) 2560 2560 infoPtr->iSelected--; … … 2573 2573 } 2574 2574 2575 static LRESULT 2575 static LRESULT 2576 2576 TAB_DeleteAllItems (HWND hwnd, WPARAM wParam, LPARAM lParam) 2577 2577 { … … 2584 2584 KillTimer(hwnd, TAB_HOTTRACK_TIMER); 2585 2585 infoPtr->iHotTracked = -1; 2586 2586 2587 2587 TAB_SetItemBounds(hwnd); 2588 2588 TAB_InvalidateTabArea(hwnd,infoPtr); … … 2605 2605 { 2606 2606 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 2607 2607 2608 2608 TRACE("%x %lx\n",wParam, lParam); 2609 2609 2610 2610 infoPtr->hFont = (HFONT)wParam; 2611 2611 2612 2612 TAB_SetItemBounds(hwnd); 2613 2613 … … 2676 2676 cx=LOWORD (lParam); 2677 2677 cy=HIWORD (lParam); 2678 if (GetWindowLongA(hwnd, GWL_STYLE) & CCS_NORESIZE) 2678 if (GetWindowLongA(hwnd, GWL_STYLE) & CCS_NORESIZE) 2679 2679 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE); 2680 2680 … … 2695 2695 2696 2696 2697 static LRESULT 2697 static LRESULT 2698 2698 TAB_Create (HWND hwnd, WPARAM wParam, LPARAM lParam) 2699 2699 { … … 2711 2711 2712 2712 SetWindowLongA(hwnd, 0, (DWORD)infoPtr); 2713 2713 2714 2714 infoPtr->uNumItem = 0; 2715 2715 infoPtr->uNumRows = 0; … … 2719 2719 infoPtr->iSelected = -1; 2720 2720 infoPtr->iHotTracked = -1; 2721 infoPtr->uFocus = -1; 2721 infoPtr->uFocus = -1; 2722 2722 infoPtr->hwndToolTip = 0; 2723 2723 infoPtr->DoRedraw = TRUE; … … 2725 2725 infoPtr->hwndUpDown = 0; 2726 2726 infoPtr->leftmostVisible = 0; 2727 infoPtr->fSizeSet 2728 infoPtr->bUnicode 2729 2730 TRACE("Created tab control, hwnd [%04x]\n", hwnd); 2731 2732 /* The tab control always has the WS_CLIPSIBLINGS style. Even 2733 if you don't specify it in CreateWindow. This is necessary in 2727 infoPtr->fSizeSet = FALSE; 2728 infoPtr->bUnicode = IsWindowUnicode (hwnd); 2729 2730 TRACE("Created tab control, hwnd [%04x]\n", hwnd); 2731 2732 /* The tab control always has the WS_CLIPSIBLINGS style. Even 2733 if you don't specify it in CreateWindow. This is necessary in 2734 2734 order for paint to work correctly. This follows windows behaviour. */ 2735 2735 dwStyle = GetWindowLongA(hwnd, GWL_STYLE); … … 2740 2740 infoPtr->hwndToolTip = 2741 2741 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0, 2742 2743 2744 2745 2742 CW_USEDEFAULT, CW_USEDEFAULT, 2743 CW_USEDEFAULT, CW_USEDEFAULT, 2744 hwnd, 0, 0, 0); 2745 2746 2746 /* Send NM_TOOLTIPSCREATED notification */ 2747 2747 if (infoPtr->hwndToolTip) { 2748 2748 NMTOOLTIPSCREATED nmttc; 2749 2749 2750 2750 nmttc.hdr.hwndFrom = hwnd; 2751 2751 nmttc.hdr.idFrom = GetWindowLongA(hwnd, GWL_ID); 2752 2752 nmttc.hdr.code = NM_TOOLTIPSCREATED; 2753 2753 nmttc.hwndToolTips = infoPtr->hwndToolTip; 2754 2754 2755 2755 SendMessageA (GetParent (hwnd), WM_NOTIFY, 2756 2757 } 2758 } 2759 2756 (WPARAM)GetWindowLongA(hwnd, GWL_ID), (LPARAM)&nmttc); 2757 } 2758 } 2759 2760 2760 /* 2761 2761 * We need to get text information so we need a DC and we need to select 2762 2762 * a font. 2763 2763 */ 2764 hdc = GetDC(hwnd); 2764 hdc = GetDC(hwnd); 2765 2765 hOldFont = SelectObject (hdc, GetStockObject (SYSTEM_FONT)); 2766 2766 … … 2769 2769 2770 2770 /* 2771 * Make sure there is enough space for the letters + growing the 2772 * selected item + extra space for the selected item. 2771 * Make sure there is enough space for the letters + growing the 2772 * selected item + extra space for the selected item. 2773 2773 */ 2774 2774 infoPtr->tabHeight = fontMetrics.tmHeight + 2 * VERTICAL_ITEM_PADDING + … … 2796 2796 for (iItem = 0; iItem < infoPtr->uNumItem; iItem++) { 2797 2797 if (infoPtr->items[iItem].pszText) 2798 2798 COMCTL32_Free (infoPtr->items[iItem].pszText); 2799 2799 } 2800 2800 COMCTL32_Free (infoPtr->items); 2801 2801 } 2802 2803 if (infoPtr->hwndToolTip) 2802 2803 if (infoPtr->hwndToolTip) 2804 2804 DestroyWindow (infoPtr->hwndToolTip); 2805 2805 2806 2806 if (infoPtr->hwndUpDown) 2807 2807 DestroyWindow(infoPtr->hwndUpDown); … … 2827 2827 case TCM_GETIMAGELIST: 2828 2828 return TAB_GetImageList (hwnd, wParam, lParam); 2829 2829 2830 2830 case TCM_SETIMAGELIST: 2831 2831 return TAB_SetImageList (hwnd, wParam, lParam); 2832 2832 2833 2833 case TCM_GETITEMCOUNT: 2834 2834 return TAB_GetItemCount (hwnd, wParam, lParam); 2835 2835 2836 2836 case TCM_GETITEMA: 2837 2837 return TAB_GetItemA (hwnd, wParam, lParam); 2838 2838 2839 2839 case TCM_GETITEMW: 2840 2840 return TAB_GetItemW (hwnd, wParam, lParam); 2841 2841 2842 2842 case TCM_SETITEMA: 2843 2843 return TAB_SetItemA (hwnd, wParam, lParam); 2844 2844 2845 2845 case TCM_SETITEMW: 2846 2846 return TAB_SetItemW (hwnd, wParam, lParam); 2847 2847 2848 2848 case TCM_DELETEITEM: 2849 2849 return TAB_DeleteItem (hwnd, wParam, lParam); 2850 2850 2851 2851 case TCM_DELETEALLITEMS: 2852 2852 return TAB_DeleteAllItems (hwnd, wParam, lParam); 2853 2853 2854 2854 case TCM_GETITEMRECT: 2855 2855 return TAB_GetItemRect (hwnd, wParam, lParam); 2856 2856 2857 2857 case TCM_GETCURSEL: 2858 2858 return TAB_GetCurSel (hwnd); 2859 2859 2860 2860 case TCM_HITTEST: 2861 2861 return TAB_HitTest (hwnd, wParam, lParam); 2862 2862 2863 2863 case TCM_SETCURSEL: 2864 2864 return TAB_SetCurSel (hwnd, wParam); 2865 2865 2866 2866 case TCM_INSERTITEMA: 2867 2867 return TAB_InsertItemA (hwnd, wParam, lParam); 2868 2868 2869 2869 case TCM_INSERTITEMW: 2870 2870 return TAB_InsertItemW (hwnd, wParam, lParam); 2871 2871 2872 2872 case TCM_SETITEMEXTRA: 2873 2873 FIXME("Unimplemented msg TCM_SETITEMEXTRA\n"); 2874 2874 return 0; 2875 2875 2876 2876 case TCM_ADJUSTRECT: 2877 2877 return TAB_AdjustRect (hwnd, (BOOL)wParam, (LPRECT)lParam); 2878 2878 2879 2879 case TCM_SETITEMSIZE: 2880 2880 return TAB_SetItemSize (hwnd, wParam, lParam); 2881 2881 2882 2882 case TCM_REMOVEIMAGE: 2883 2883 FIXME("Unimplemented msg TCM_REMOVEIMAGE\n"); 2884 2884 return 0; 2885 2885 2886 2886 case TCM_SETPADDING: 2887 2887 FIXME("Unimplemented msg TCM_SETPADDING\n"); 2888 2888 return 0; 2889 2889 2890 2890 case TCM_GETROWCOUNT: 2891 2891 return TAB_GetRowCount(hwnd); … … 2900 2900 FIXME("Unimplemented msg TCM_HIGHLIGHTITEM\n"); 2901 2901 return 0; 2902 2902 2903 2903 case TCM_GETTOOLTIPS: 2904 2904 return TAB_GetToolTips (hwnd, wParam, lParam); 2905 2905 2906 2906 case TCM_SETTOOLTIPS: 2907 2907 return TAB_SetToolTips (hwnd, wParam, lParam); 2908 2908 2909 2909 case TCM_GETCURFOCUS: 2910 2910 return TAB_GetCurFocus (hwnd); 2911 2911 2912 2912 case TCM_SETCURFOCUS: 2913 2913 return TAB_SetCurFocus (hwnd, wParam); 2914 2914 2915 2915 case TCM_SETMINTABWIDTH: 2916 2916 FIXME("Unimplemented msg TCM_SETMINTABWIDTH\n"); 2917 2917 return 0; 2918 2918 2919 2919 case TCM_DESELECTALL: 2920 2920 FIXME("Unimplemented msg TCM_DESELECTALL\n"); 2921 2921 return 0; 2922 2922 2923 2923 case TCM_GETEXTENDEDSTYLE: 2924 2924 FIXME("Unimplemented msg TCM_GETEXTENDEDSTYLE\n"); … … 2931 2931 case WM_GETFONT: 2932 2932 return TAB_GetFont (hwnd, wParam, lParam); 2933 2933 2934 2934 case WM_SETFONT: 2935 2935 return TAB_SetFont (hwnd, wParam, lParam); 2936 2936 2937 2937 case WM_CREATE: 2938 2938 return TAB_Create (hwnd, wParam, lParam); 2939 2939 2940 2940 case WM_NCDESTROY: 2941 2941 return TAB_Destroy (hwnd, wParam, lParam); 2942 2942 2943 2943 case WM_GETDLGCODE: 2944 2944 return DLGC_WANTARROWS | DLGC_WANTCHARS; 2945 2945 2946 2946 case WM_LBUTTONDOWN: 2947 2947 return TAB_LButtonDown (hwnd, wParam, lParam); 2948 2948 2949 2949 case WM_LBUTTONUP: 2950 2950 return TAB_LButtonUp (hwnd, wParam, lParam); 2951 2951 2952 2952 case WM_RBUTTONDOWN: 2953 2953 return TAB_RButtonDown (hwnd, wParam, lParam); 2954 2954 2955 2955 case WM_MOUSEMOVE: 2956 2956 return TAB_MouseMove (hwnd, wParam, lParam); 2957 2957 2958 2958 case WM_ERASEBKGND: 2959 2959 return TAB_EraseBackground (hwnd, (HDC)wParam); … … 2964 2964 case WM_SIZE: 2965 2965 return TAB_Size (hwnd, wParam, lParam); 2966 2966 2967 2967 case WM_SETREDRAW: 2968 2968 return TAB_SetRedraw (hwnd, wParam); … … 2975 2975 InvalidateRect(hwnd, NULL, TRUE); 2976 2976 return 0; 2977 2977 2978 2978 case WM_KILLFOCUS: 2979 2979 case WM_SETFOCUS: … … 2987 2987 default: 2988 2988 if (uMsg >= WM_USER) 2989 2990 2989 WARN("unknown msg %04x wp=%08x lp=%08lx\n", 2990 uMsg, wParam, lParam); 2991 2991 #ifdef __WIN32OS2__ 2992 2992 return defComCtl32ProcA (hwnd, uMsg, wParam, lParam); … … 3013 3013 wndClass.hbrBackground = (HBRUSH)NULL; 3014 3014 wndClass.lpszClassName = WC_TABCONTROLA; 3015 3015 3016 3016 RegisterClassA (&wndClass); 3017 3017 }
Note:
See TracChangeset
for help on using the changeset viewer.