1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Sound Volume Control 4 * FILE: base/applications/sndvol32/dialog.c 5 * PROGRAMMERS: Johannes Anderwald 6 */ 7 8 #include "sndvol32.h" 9 10 11 VOID 12 ConvertRect(LPRECT lpRect, UINT xBaseUnit, UINT yBaseUnit) 13 { 14 lpRect->left = MulDiv(lpRect->left, xBaseUnit, 4); 15 lpRect->right = MulDiv(lpRect->right, xBaseUnit, 4); 16 lpRect->top = MulDiv(lpRect->top, yBaseUnit, 8); 17 lpRect->bottom = MulDiv(lpRect->bottom, yBaseUnit, 8); 18 } 19 20 LPVOID 21 LoadDialogResource( 22 IN HMODULE hModule, 23 IN LPCWSTR ResourceName, 24 OUT LPDWORD ResourceLength) 25 { 26 HRSRC hSrc; 27 HGLOBAL hRes; 28 PVOID Result; 29 30 /* find resource */ 31 hSrc = FindResourceW(hModule, ResourceName, (LPCWSTR)RT_DIALOG); 32 33 if (!hSrc) 34 { 35 /* failed to find resource */ 36 return NULL; 37 } 38 39 /* now load the resource */ 40 hRes = LoadResource(hAppInstance, hSrc); 41 if (!hRes) 42 { 43 /* failed to load resource */ 44 return NULL; 45 } 46 47 /* now lock the resource */ 48 Result = LockResource(hRes); 49 50 if (!Result) 51 { 52 /* failed to lock resource */ 53 return NULL; 54 } 55 56 if (ResourceLength) 57 { 58 /* store output length */ 59 *ResourceLength = SizeofResource(hAppInstance, hSrc); 60 } 61 62 /* done */ 63 return Result; 64 } 65 66 LPWORD 67 AddDialogControl( 68 IN HWND hwndDialog, 69 OUT HWND *OutWnd, 70 IN LPRECT DialogOffset, 71 IN PDLGITEMTEMPLATE DialogItem, 72 IN DWORD DialogIdMultiplier, 73 IN HFONT hFont, 74 IN UINT xBaseUnit, 75 IN UINT yBaseUnit, 76 IN UINT MixerId) 77 { 78 RECT rect; 79 LPWORD Offset; 80 LPWSTR ClassName, WindowName = NULL; 81 HWND hwnd; 82 DWORD wID; 83 INT nSteps, i; 84 85 /* initialize client rectangle */ 86 rect.left = DialogItem->x; 87 rect.top = DialogItem->y; 88 rect.right = DialogItem->x + DialogItem->cx; 89 rect.bottom = DialogItem->y + DialogItem->cy; 90 91 /* Convert Dialog units to pixes */ 92 ConvertRect(&rect, xBaseUnit, yBaseUnit); 93 94 rect.left += DialogOffset->left; 95 rect.right += DialogOffset->left; 96 rect.top += DialogOffset->top; 97 rect.bottom += DialogOffset->top; 98 99 /* move offset after dialog item */ 100 Offset = (LPWORD)(DialogItem + 1); 101 102 if (*Offset == 0xFFFF) 103 { 104 /* class is encoded as type */ 105 Offset++; 106 107 /* get control type */ 108 switch(*Offset) 109 { 110 case 0x80: 111 ClassName = L"button"; 112 WindowName = (LPWSTR)(Offset + 1); 113 break ; 114 case 0x82: 115 ClassName = L"static"; 116 WindowName = (LPWSTR)(Offset + 1); 117 break; 118 default: 119 /* FIXME */ 120 assert(0); 121 ClassName = NULL; 122 } 123 } 124 else 125 { 126 /* class name is encoded as string */ 127 ClassName = (LPWSTR)Offset; 128 129 /* move offset to the end of class string */ 130 Offset += wcslen(ClassName); 131 132 /* get window name */ 133 WindowName = (LPWSTR)(Offset + 1); 134 } 135 136 /* move offset past class type/string */ 137 Offset++; 138 139 if (DialogItem->id == MAXWORD) 140 { 141 /* id is not important */ 142 wID = DialogItem->id; 143 } 144 else 145 { 146 /* calculate id */ 147 wID = DialogItem->id * (DialogIdMultiplier + 1); 148 149 } 150 151 /* now create the window */ 152 hwnd = CreateWindowExW(DialogItem->dwExtendedStyle, 153 ClassName, 154 WindowName, 155 DialogItem->style, 156 rect.left, 157 rect.top, 158 rect.right - rect.left, 159 rect.bottom - rect.top, 160 hwndDialog, 161 UlongToPtr(wID), 162 hAppInstance, 163 NULL); 164 165 /* sanity check */ 166 assert(hwnd); 167 168 /* store window */ 169 *OutWnd = hwnd; 170 171 /* check if this the track bar */ 172 if (!wcsicmp(ClassName, L"msctls_trackbar32")) 173 { 174 if (DialogItem->style & TBS_VERT) 175 { 176 /* Vertical trackbar: Volume */ 177 178 /* Disable the volume trackbar by default */ 179 EnableWindow(hwnd, FALSE); 180 181 /* set up range */ 182 SendMessage(hwnd, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(VOLUME_MIN, VOLUME_MAX)); 183 184 /* set up page size */ 185 SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)VOLUME_PAGE_SIZE); 186 187 /* set position */ 188 SendMessage(hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)0); 189 190 /* Calculate and set ticks */ 191 nSteps = (VOLUME_MAX / (VOLUME_TICKS + 1)); 192 if (VOLUME_MAX % (VOLUME_TICKS + 1) != 0) 193 nSteps++; 194 for (i = nSteps; i < VOLUME_MAX; i += nSteps) 195 SendMessage(hwnd, TBM_SETTIC, 0, (LPARAM)i); 196 } 197 else 198 { 199 /* Horizontal trackbar: Balance */ 200 201 /* Disable the balance trackbar by default */ 202 EnableWindow(hwnd, FALSE); 203 204 /* set up range */ 205 SendMessage(hwnd, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, BALANCE_STEPS)); 206 207 /* set up page size */ 208 SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)BALANCE_PAGE_SIZE); 209 210 /* set position */ 211 SendMessage(hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)BALANCE_STEPS / 2); 212 213 /* Calculate and set ticks */ 214 nSteps = (BALANCE_STEPS / (BALANCE_TICKS + 1)); 215 if (BALANCE_STEPS % (BALANCE_TICKS + 1) != 0) 216 nSteps++; 217 for (i = nSteps; i < BALANCE_STEPS; i += nSteps) 218 SendMessage(hwnd, TBM_SETTIC, 0, (LPARAM)i); 219 } 220 } 221 else if (!wcsicmp(ClassName, L"static")) 222 { 223 /* Set font */ 224 SendMessageW(hwnd, WM_SETFONT, (WPARAM)hFont, TRUE); 225 } 226 else if (!wcsicmp(ClassName, L"button")) 227 { 228 if (DialogItem->id == IDC_LINE_SWITCH) 229 { 230 if (MixerId == PLAY_MIXER) 231 { 232 /* Disable checkboxes by default, if we are in play mode */ 233 EnableWindow(hwnd, FALSE); 234 } 235 } 236 else if (DialogItem->id == IDC_LINE_ADVANCED) 237 { 238 ShowWindow(hwnd, SW_HIDE); 239 } 240 241 /* Set font */ 242 SendMessageW(hwnd, WM_SETFONT, (WPARAM)hFont, TRUE); 243 } 244 245 if (WindowName != NULL) 246 { 247 /* move offset past window name */ 248 Offset += wcslen(WindowName) + 1; 249 } 250 251 /* check if there is additional data */ 252 if (*Offset == 0) 253 { 254 /* no additional data */ 255 Offset++; 256 } 257 else 258 { 259 /* FIXME: Determine whether this should be "Offset += 1 + *Offset" to explicitly skip the data count too. */ 260 /* skip past additional data */ 261 Offset += *Offset; 262 } 263 264 /* make sure next template is word-aligned */ 265 Offset = (LPWORD)(((ULONG_PTR)Offset + 3) & ~3); 266 267 /* done */ 268 return Offset; 269 } 270 271 VOID 272 LoadDialogControls( 273 IN PMIXER_WINDOW MixerWindow, 274 LPRECT DialogOffset, 275 WORD ItemCount, 276 PDLGITEMTEMPLATE DialogItem, 277 DWORD DialogIdMultiplier, 278 UINT xBaseUnit, 279 UINT yBaseUnit) 280 { 281 LPWORD Offset; 282 WORD Index; 283 284 /* sanity check */ 285 assert(ItemCount); 286 287 if (MixerWindow->Window) 288 MixerWindow->Window = (HWND*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MixerWindow->Window, (MixerWindow->WindowCount + ItemCount) * sizeof(HWND)); 289 else 290 MixerWindow->Window = (HWND*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ItemCount * sizeof(HWND)); 291 if (!MixerWindow->Window) 292 { 293 /* no memory */ 294 return; 295 } 296 297 /* enumerate now all controls */ 298 for (Index = 0; Index < ItemCount; Index++) 299 { 300 /* add controls */ 301 Offset = AddDialogControl(MixerWindow->hWnd, 302 &MixerWindow->Window[MixerWindow->WindowCount], 303 DialogOffset, 304 DialogItem, 305 DialogIdMultiplier, 306 MixerWindow->hFont, 307 xBaseUnit, 308 yBaseUnit, 309 MixerWindow->MixerId); 310 311 /* sanity check */ 312 assert(Offset); 313 314 /* move dialog item to new offset */ 315 DialogItem =(PDLGITEMTEMPLATE)Offset; 316 317 /* increment window count */ 318 MixerWindow->WindowCount++; 319 } 320 } 321 322 VOID 323 LoadDialog( 324 IN HMODULE hModule, 325 IN PMIXER_WINDOW MixerWindow, 326 IN LPCWSTR DialogResId, 327 IN DWORD Index) 328 { 329 LPDLGTEMPLATE DlgTemplate; 330 PDLGITEMTEMPLATE DlgItem; 331 RECT dialogRect; 332 LPWORD Offset; 333 WORD FontSize; 334 WCHAR FontName[100]; 335 WORD Length; 336 int width; 337 338 DWORD units = GetDialogBaseUnits(); 339 UINT xBaseUnit = LOWORD(units); 340 UINT yBaseUnit = HIWORD(units); 341 342 /* first load the dialog resource */ 343 DlgTemplate = (LPDLGTEMPLATE)LoadDialogResource(hModule, DialogResId, NULL); 344 if (!DlgTemplate) 345 { 346 /* failed to load resource */ 347 return; 348 } 349 350 /* Now walk past the dialog header */ 351 Offset = (LPWORD)(DlgTemplate + 1); 352 353 /* FIXME: support menu */ 354 assert(*Offset == 0); 355 Offset++; 356 357 /* FIXME: support classes */ 358 assert(*Offset == 0); 359 Offset++; 360 361 /* FIXME: support titles */ 362 assert(*Offset == 0); 363 Offset++; 364 365 /* get font size */ 366 FontSize = *Offset; 367 Offset++; 368 369 /* calculate font length */ 370 Length = wcslen((LPWSTR)Offset) + 1; 371 assert(Length < (sizeof(FontName) / sizeof(WCHAR))); 372 373 /* copy font */ 374 wcscpy(FontName, (LPWSTR)Offset); 375 376 if (DlgTemplate->style & DS_SETFONT) 377 { 378 HDC hDC; 379 380 hDC = GetDC(0); 381 382 if (!MixerWindow->hFont) 383 { 384 int pixels = MulDiv(FontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72); 385 MixerWindow->hFont = CreateFontW(-pixels, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, FontName); 386 } 387 388 if (MixerWindow->hFont) 389 { 390 SIZE charSize; 391 HFONT hOldFont; 392 393 hOldFont = SelectObject(hDC, MixerWindow->hFont); 394 charSize.cx = GdiGetCharDimensions(hDC, NULL, &charSize.cy); 395 if (charSize.cx) 396 { 397 xBaseUnit = charSize.cx; 398 yBaseUnit = charSize.cy; 399 } 400 SelectObject(hDC, hOldFont); 401 402 MixerWindow->baseUnit.cx = charSize.cx; 403 MixerWindow->baseUnit.cy = charSize.cy; 404 } 405 } 406 407 // assert(MixerWindow->hFont); 408 409 /* move offset after font name */ 410 Offset += Length; 411 412 /* offset is now at first dialog item control */ 413 DlgItem = (PDLGITEMTEMPLATE)Offset; 414 415 dialogRect.left = 0; 416 dialogRect.right = DlgTemplate->cx; 417 dialogRect.top = 0; 418 dialogRect.bottom = DlgTemplate->cy; 419 420 ConvertRect(&dialogRect, xBaseUnit, yBaseUnit); 421 422 width = dialogRect.right - dialogRect.left; 423 424 dialogRect.left += MixerWindow->rect.right; 425 dialogRect.right += MixerWindow->rect.right; 426 dialogRect.top += MixerWindow->rect.top; 427 dialogRect.bottom += MixerWindow->rect.top; 428 429 MixerWindow->rect.right += width; 430 if ((dialogRect.bottom - dialogRect.top) > (MixerWindow->rect.bottom - MixerWindow->rect.top)) 431 MixerWindow->rect.bottom = MixerWindow->rect.top + dialogRect.bottom - dialogRect.top; 432 433 /* now add the controls */ 434 LoadDialogControls(MixerWindow, &dialogRect, DlgTemplate->cdit, DlgItem, Index, xBaseUnit, yBaseUnit); 435 } 436 437 BOOL 438 CALLBACK 439 EnumConnectionsCallback( 440 PSND_MIXER Mixer, 441 DWORD LineID, 442 LPMIXERLINE Line, 443 PVOID Context) 444 { 445 WCHAR LineName[MIXER_LONG_NAME_CHARS]; 446 DWORD Flags; 447 DWORD wID; 448 UINT ControlCount = 0, Index; 449 LPMIXERCONTROL Control = NULL; 450 HWND hDlgCtrl; 451 PMIXERCONTROLDETAILS_UNSIGNED pVolumeDetails = NULL; 452 PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context; 453 454 if (Line->cControls == 0) 455 return TRUE; 456 457 /* get line name */ 458 if (SndMixerGetLineName(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, LineName, MIXER_LONG_NAME_CHARS, TRUE) == -1) 459 { 460 /* failed to get line name */ 461 LineName[0] = L'\0'; 462 } 463 464 pVolumeDetails = HeapAlloc(GetProcessHeap(), 465 0, 466 Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED)); 467 if (pVolumeDetails == NULL) 468 goto done; 469 470 /* check if line is found in registry settings */ 471 if (ReadLineConfig(PrefContext->DeviceName, 472 LineName, 473 Line->szName, 474 &Flags)) 475 { 476 /* is it selected */ 477 if (Flags != 0x4) 478 { 479 int dlgId; 480 481 if ((Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS) || 482 (Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_HEADPHONES)) 483 dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_MASTER : IDD_NORMAL_MASTER; 484 else 485 dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_LINE : IDD_NORMAL_LINE; 486 487 /* load dialog resource */ 488 LoadDialog(hAppInstance, PrefContext->MixerWindow, MAKEINTRESOURCE(dlgId), PrefContext->MixerWindow->DialogCount); 489 490 /* get id */ 491 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_NAME; 492 493 /* set line name */ 494 SetDlgItemTextW(PrefContext->MixerWindow->hWnd, wID, Line->szName); 495 496 /* query controls */ 497 if (SndMixerQueryControls(Mixer, &ControlCount, Line, &Control) != FALSE) 498 { 499 /* now go through all controls and update their states */ 500 for (Index = 0; Index < Line->cControls; Index++) 501 { 502 if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) 503 { 504 MIXERCONTROLDETAILS_BOOLEAN Details; 505 506 /* get volume control details */ 507 if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, 1, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&Details) != -1) 508 { 509 /* update dialog control */ 510 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SWITCH; 511 512 /* get dialog control */ 513 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID); 514 515 if (hDlgCtrl != NULL) 516 { 517 /* Enable the 'Mute' checkbox, if we are in play mode */ 518 if (Mixer->MixerId == PLAY_MIXER) 519 EnableWindow(hDlgCtrl, TRUE); 520 521 /* check state */ 522 if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != Details.fValue) 523 { 524 /* update control state */ 525 SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)Details.fValue, 0); 526 } 527 } 528 } 529 } 530 else if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME) 531 { 532 /* get volume control details */ 533 if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, Line->cChannels, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)pVolumeDetails) != -1) 534 { 535 /* update dialog control */ 536 DWORD volumePosition, volumeStep, maxVolume, i; 537 DWORD balancePosition, balanceStep; 538 539 volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN); 540 541 maxVolume = 0; 542 for (i = 0; i < Line->cChannels; i++) 543 { 544 if (pVolumeDetails[i].dwValue > maxVolume) 545 maxVolume = pVolumeDetails[i].dwValue; 546 } 547 548 volumePosition = (maxVolume - Control[Index].Bounds.dwMinimum) / volumeStep; 549 550 if (Line->cChannels == 1) 551 { 552 balancePosition = BALANCE_CENTER; 553 } 554 else if (Line->cChannels == 2) 555 { 556 if (pVolumeDetails[0].dwValue == pVolumeDetails[1].dwValue) 557 { 558 balancePosition = BALANCE_CENTER; 559 } 560 else if (pVolumeDetails[0].dwValue == Control[Index].Bounds.dwMinimum) 561 { 562 balancePosition = BALANCE_RIGHT; 563 } 564 else if (pVolumeDetails[1].dwValue == Control[Index].Bounds.dwMinimum) 565 { 566 balancePosition = BALANCE_LEFT; 567 } 568 else 569 { 570 balanceStep = (maxVolume - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2); 571 572 if (pVolumeDetails[0].dwValue < pVolumeDetails[1].dwValue) 573 { 574 balancePosition = (pVolumeDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep; 575 balancePosition = BALANCE_RIGHT - balancePosition; 576 } 577 else if (pVolumeDetails[1].dwValue < pVolumeDetails[0].dwValue) 578 { 579 balancePosition = (pVolumeDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep; 580 balancePosition = BALANCE_LEFT + balancePosition; 581 } 582 } 583 } 584 585 /* Set the volume trackbar */ 586 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SLIDER_VERT; 587 588 /* get dialog control */ 589 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID); 590 591 if (hDlgCtrl != NULL) 592 { 593 /* check state */ 594 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0); 595 596 /* Enable the volume trackbar */ 597 EnableWindow(hDlgCtrl, TRUE); 598 599 if (OldPosition != (VOLUME_MAX - volumePosition)) 600 { 601 /* update control state */ 602 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, VOLUME_MAX - volumePosition); 603 } 604 } 605 606 if (Line->cChannels == 2) 607 { 608 /* Set the balance trackbar */ 609 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SLIDER_HORZ; 610 611 /* get dialog control */ 612 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID); 613 614 if (hDlgCtrl != NULL) 615 { 616 /* check state */ 617 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0); 618 619 /* Enable the balance trackbar */ 620 EnableWindow(hDlgCtrl, TRUE); 621 622 if (OldPosition != balancePosition) 623 { 624 /* update control state */ 625 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, balancePosition); 626 } 627 } 628 } 629 } 630 } 631 else 632 { 633 if (PrefContext->MixerWindow->Mode == NORMAL_MODE) 634 PrefContext->MixerWindow->bHasExtendedControls = TRUE; 635 } 636 } 637 638 /* free controls */ 639 HeapFree(GetProcessHeap(), 0, Control); 640 } 641 642 /* increment dialog count */ 643 PrefContext->MixerWindow->DialogCount++; 644 } 645 } 646 647 done: 648 /* Free the volume details */ 649 if (pVolumeDetails) 650 HeapFree(GetProcessHeap(), 0, pVolumeDetails); 651 652 return TRUE; 653 } 654 655 VOID 656 LoadDialogCtrls( 657 PPREFERENCES_CONTEXT PrefContext) 658 { 659 HWND hDlgCtrl; 660 RECT statusRect; 661 662 /* set dialog count to zero */ 663 PrefContext->MixerWindow->DialogCount = 0; 664 665 SetRectEmpty(&PrefContext->MixerWindow->rect); 666 667 /* enumerate controls */ 668 SndMixerEnumConnections(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, EnumConnectionsCallback, (PVOID)PrefContext); 669 670 if (PrefContext->MixerWindow->bHasExtendedControls) 671 { 672 EnableMenuItem(GetMenu(PrefContext->MixerWindow->hWnd), IDM_ADVANCED_CONTROLS, MF_BYCOMMAND | MF_ENABLED); 673 } 674 675 if (PrefContext->MixerWindow->hStatusBar) 676 { 677 GetWindowRect(PrefContext->MixerWindow->hStatusBar, &statusRect); 678 PrefContext->MixerWindow->rect.bottom += (statusRect.bottom - statusRect.top); 679 } 680 681 /* now move the window */ 682 AdjustWindowRect(&PrefContext->MixerWindow->rect, WS_DLGFRAME | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE, TRUE); 683 SetWindowPos(PrefContext->MixerWindow->hWnd, HWND_TOP, PrefContext->MixerWindow->rect.left, PrefContext->MixerWindow->rect.top, PrefContext->MixerWindow->rect.right - PrefContext->MixerWindow->rect.left, PrefContext->MixerWindow->rect.bottom - PrefContext->MixerWindow->rect.top, SWP_NOMOVE | SWP_NOZORDER); 684 685 /* Move the status bar */ 686 if (PrefContext->MixerWindow->hStatusBar) 687 { 688 SetWindowPos(PrefContext->MixerWindow->hStatusBar, 689 HWND_TOP, 690 statusRect.left, 691 PrefContext->MixerWindow->rect.bottom - (statusRect.bottom - statusRect.top), 692 PrefContext->MixerWindow->rect.right - PrefContext->MixerWindow->rect.left, 693 statusRect.bottom - statusRect.top, 694 SWP_NOZORDER); 695 } 696 697 /* Hide the last line separator */ 698 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, IDC_LINE_SEP * PrefContext->MixerWindow->DialogCount /*PrefContext->Count*/); 699 if (hDlgCtrl != NULL) 700 { 701 ShowWindow(hDlgCtrl, SW_HIDE); 702 } 703 } 704 705 VOID 706 UpdateDialogLineSwitchControl( 707 PPREFERENCES_CONTEXT PrefContext, 708 LPMIXERLINE Line, 709 LONG fValue) 710 { 711 DWORD Index; 712 DWORD wID; 713 HWND hDlgCtrl; 714 WCHAR LineName[MIXER_LONG_NAME_CHARS]; 715 716 /* find the index of this line */ 717 for (Index = 0; Index < PrefContext->MixerWindow->DialogCount; Index++) 718 { 719 /* get id */ 720 wID = (Index + 1) * IDC_LINE_NAME; 721 722 if (GetDlgItemText(PrefContext->MixerWindow->hWnd, wID, LineName, MIXER_LONG_NAME_CHARS) == 0) 723 { 724 /* failed to retrieve id */ 725 continue; 726 } 727 728 /* check if the line name matches */ 729 if (!wcsicmp(LineName, Line->szName)) 730 { 731 /* found matching line name */ 732 wID = (Index + 1) * IDC_LINE_SWITCH; 733 734 /* get dialog control */ 735 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID); 736 737 if (hDlgCtrl != NULL) 738 { 739 /* check state */ 740 if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != fValue) 741 { 742 /* update control state */ 743 SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)fValue, 0); 744 } 745 } 746 break; 747 } 748 } 749 } 750 751 VOID 752 UpdateDialogLineSliderControl( 753 PPREFERENCES_CONTEXT PrefContext, 754 LPMIXERLINE Line, 755 DWORD dwDialogID, 756 DWORD Position) 757 { 758 DWORD Index; 759 DWORD wID; 760 HWND hDlgCtrl; 761 WCHAR LineName[MIXER_LONG_NAME_CHARS]; 762 763 /* find the index of this line */ 764 for (Index = 0; Index < PrefContext->MixerWindow->DialogCount; Index++) 765 { 766 /* get id */ 767 wID = (Index + 1) * IDC_LINE_NAME; 768 769 if (GetDlgItemText(PrefContext->MixerWindow->hWnd, wID, LineName, MIXER_LONG_NAME_CHARS) == 0) 770 { 771 /* failed to retrieve id */ 772 continue; 773 } 774 775 /* check if the line name matches */ 776 if (!wcsicmp(LineName, Line->szName)) 777 { 778 /* found matching line name */ 779 wID = (Index + 1) * dwDialogID; 780 781 /* get dialog control */ 782 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID); 783 784 if (hDlgCtrl != NULL) 785 { 786 /* check state */ 787 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0); 788 if (OldPosition != Position) 789 { 790 /* update control state */ 791 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, Position); 792 } 793 } 794 break; 795 } 796 } 797 } 798