Radek Chalupa   konzultace a školení programování, vývoj software na zakázku

Ovládací prvek TrackBar.

5.2.2002

V tomto článku se zaměříme na další ze standardních ovládacích prvků Windows, kterým je Trackbar Control.

win-api-trackbar

Aby byla aplikace používající prvek Trackbar funkční, musíme na jejím  začátku - přesněji řečeno před vytvořením okna (nebo více oken) prvku Trackbar použít funkci InitCommonControlsEx podobně jako u dalších prvků obsažených v knihovně comctl32.dll. S tím také souvisí nutnost přidat pro linkování do projektu odpovídající knihovnu comctl32.lib a vložit hlavičkový soubor commctrl.h.
// Běžné hlavičkové soubory 
#include <commctrl.h>	

// linkeru přidáme knihovnu přímo ve zdrojovém kódu
#pragma comment (lib, "comctl32.lib")
Ukázkový projekt je aplikace založená na hlavním okně dialogu. V editoru prostředků přidáme na dialog prvek Trackbar, který v okně Toolbox nalezneme pod poněkud matoucím označení Slider Control.

Nastavení vlastností v editoru prostředků

Přímo v editoru prostředků máme možnost nastavit různé vlastnosti (styly okna) Trackbaru. Řekněme si o významu některých z nich.
  • Orientation - určuje orientaci, která může být ve vodorovném nebo svislém směru. Vlastnost může nabývat hodnot Horizontal nebo Vertical, což odpovídá stylům okna (které použijeme při "ručním" vytvoření) TBS_HORZ (výchozí vlatsnost) a TBS_VERT.
  • Tick Marks - určuje zda je povoleno zobrazovat značky v bodech odpovídajících jednotlivým polohám nebo jejich násobkům (hustotu - krokování značek lze nastavit programově). Odpovídající stylu okna je TBS_NOTICKS, který značky zakazuje!
  • Auto Ticks - pokud je nastavena na True, značky jsou zobrazeny systémem automaticky.
  • Point - určuje zda se mají značky zobarzovat na obou stranách (hodnota Both) nebo pouze na levé/horní (podle orientace Trackbaru) - hodnota Top/Left či pravé/spodní - hodnota bottom/Right. Odpovídající styly okna jsou TBS_LEFT, TBS_TOP, TBS_RIGHT a TBS_BOTTOM. Nastavení zobrazování pouze na jedné straně také způsobí změnu vzhledu jezdce, který bude na příslušné straně zobrazen do špičky.
  • Tooltips - určuje zda se při tažení jezdce má zobrazovat aktuální poloha v okně tooltipu, vytvářeného a obsluhovaného systémem. Na obrázku jde o to žluté plovoucí okénko zobrazující polohu 23.

Programové ovládání Trackbaru

Jednou z prvních věcí která nás napadne, je nastavení rozsahu (v počtu logických jednotek - kroků) a dále třeba nastavení výchozí pozice. Následující funkce volaná v obsluze zprávy WM_INIDIALOG nastaví pomocí zpráv TBM_SETRANGE a TBM_SETPOS rozsah 30 logických jednotek a umístí jezdce do výchozí polohy 10.
void NastavRozsah(HWND hWnd)
{
  SendDlgItemMessage(hWnd, IDC_TRACKBAR, TBM_SETRANGE,
    TRUE, MAKELONG(0,30));
  SendDlgItemMessage(hWnd, IDC_TRACKBAR, TBM_SETPOS,
    TRUE, 10);
}
Pokud povolíme zobrazování značek, máme možnost kromě automatického zobrazení zobrazit vlastní značky v libovolných místech. Systém pak automaticky zobrazí značky počátku a konce. V našem příkladě takto nastavíme dvě vlastní značky na pozice 5 a 25 pomocí funkce TBM_SETTIC.
#define DOLNI_MEZ 5
#define HORNI_MEZ 25

void NastavZnacky(HWND hWnd)
{
  SendDlgItemMessage(hWnd, IDC_TRACKBAR, TBM_SETTIC, 0, (WPARAM)DOLNI_MEZ);
  SendDlgItemMessage(hWnd, IDC_TRACKBAR, TBM_SETTIC, 0, (WPARAM)HORNI_MEZ);
}
Mezi základní akce s Trackbarem dále patří programové zjištění aktuálně nastavené polohy a dále okamžitá detekce změny polohy. Touto změnou polohy je zde myšlena změna aktuální hodnoty logické souřadnice která většinou neodpovídá grafickému posunutí jezdce o každý pixel, ale dojde k ní v závislosti na poměru rozsahu a velikosti okna Trackbaru obvykle skokově při posunu o určitý počet pixelů. Logickou souřadnici získáme pomocí zprávy TBM_GETPOS, jak si ukážeme za chvíli v příkladu. Pokud jde o detekci změny souřadnice, musíme zachytávat zprávu WM_HSCROLL v případě horizontálního Trackbaru nebo WM_VSCROLL u svislého Trackbaru. Ukážeme si to na následujícím příkladě. Cílem bude detekovat změnu polohy a v případě že se uživatel dostane mimo rozsah dříve nastavených bodů (pozice 5 a 25) změníme ikonu na dialogu na systémovou ikonu "chyba" (IDI_ERROR). Při opětném návratu do "správných mezí" opět vrátíme ikonu na vlastní ikonu aplikace. Nastavení ikony provedeme pomocí zprávy STM_SETIMAGE prvku static, což je v editoru prostředků prvek Picture Control typu Icon. Navíc při pohybu v zakázané oblasti přehrajeme varovný zvuk - zde pro jednoduchost pomocí funkce MessageBeep. Takto bude tedy vypadat funkce realizující uvedenou kontrolu mezí a procedura dialogu, ze které jsou také volány ostatní výše uvedené funkce.
// Obsluha zprávy WM_HSCROLL
void ZmenaPolohy(HWND hWnd)
{
  LRESULT pozice =
    SendDlgItemMessage(hWnd, IDC_TRACKBAR, TBM_GETPOS, 0, 0);
  SetDlgItemInt(hWnd, IDC_POLOHA, pozice, FALSE);
  if ( pozice < DOLNI_MEZ || pozice > HORNI_MEZ )
  {
    if ( g_OK )
    {
      g_OK = FALSE;
      SendDlgItemMessage(hWnd, IDC_IKONA, STM_SETIMAGE,
        IMAGE_ICON, (LPARAM)LoadIcon(NULL, IDI_ERROR));
    }
    MessageBeep(MB_ICONERROR);
  }
  else
  {
    if ( !g_OK )
    {
      g_OK = TRUE;
      SendDlgItemMessage(hWnd, IDC_IKONA, STM_SETIMAGE, IMAGE_ICON,
        (LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_HLAVNI)));
    }
  }
}

/////////////////////////////////////////////////////////////////////////////
// Procedura dialogu

INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch ( uMsg )
  {
    case WM_COMMAND:
      switch ( LOWORD(wParam) )
      {
        case IDOK:
          EndDialog(hWnd, IDOK);
          break;
        case IDCANCEL:
          EndDialog(hWnd, IDCANCEL);
          break;
      }
      break;
      
    case WM_INITDIALOG:
      NastavRozsah(hWnd);
      NastavZnacky(hWnd);
      ZmenaPolohy(hWnd);
      break;
    case WM_HSCROLL:
      ZmenaPolohy(hWnd);
      break;
  }
  return FALSE;
}
Doprovodný projekt je ke stažení zde: win_api_trackbar.zip