|
| БЕСПЛАТНАЯ ежедневная online лотерея! Выигрывай каждый день БЕСПЛАТНО! |
|
|
Creating an Owner-Drawn List Box
The following example shows how to draw a list box that contains five owner-drawn items: four drawing implements and a fork. Each list item appears as a bitmap followed by the name of the object. A button prompts the user to select one item that is not like the others. Choosing the button with the fork selected displays a "You're right!" message and closes the dialog box. Choosing the button with any other list item selected displays a "Try again!" message.
The list box has the LBS_OWNERDRAW and LBS_HASSTRINGS styles, in addition to the standard list box styles. The code initializes the list box by sending the LB_ADDSTRING message to set the text, and then sends the LB_SETITEMDATA message to associate a bitmap with each list box item. The code also sets the height of each list box item by processing the WM_MEASUREITEM message and draws the text and bitmap for each item by processing the WM_DRAWITEM message.
#define XBITMAP 80 #define YBITMAP 20 #define BUFFER MAX_PATH HBITMAP hbmpPencil, hbmpCrayon, hbmpMarker, hbmpPen, hbmpFork; HBITMAP hbmpPicture, hbmpOld; void AddItem(HWND hwnd, LPSTR lpstr, HBITMAP hbmp) { int nItem; nItem = SendMessage(hwndList, LB_ADDSTRING, 0, lpstr); SendMessage(hwndList, LB_SETITEMDATA, nItem, hbmp); } DWORD APIENTRY DlgDrawProc( HWND hDlg, /* window handle of dialog box */
UINT message, /* type of message */ UINT wParam, /* message-specific information */ LONG lParam) { int nItem; TCHAR tchBuffer[BUFFER]; HBITMAP hbmp; HWND hListBox; TEXTMETRIC tm; int y; HDC hdcMem; LPMEASUREITEMSTRUCT lpmis; LPDRAWITEMSTRUCT lpdis; RECT rcBitmap; switch (message) { case WM_INITDIALOG: /* Load bitmaps. */
hbmpPencil = LoadBitmap(hinst, MAKEINTRESOURCE(700)); hbmpCrayon = LoadBitmap(hinst, MAKEINTRESOURCE(701)); hbmpMarker = LoadBitmap(hinst, MAKEINTRESOURCE(702)); hbmpPen = LoadBitmap(hinst, MAKEINTRESOURCE(703)); hbmpFork = LoadBitmap(hinst, MAKEINTRESOURCE(704)); /* Retrieve list box handle. */ hListBox = GetDlgItem(hDlg, IDL_STUFF); /* * Initialize the list box text and associate a bitmap
* with each list box item. */ AddItem(hListBox, "pencil", hbmpPencil); AddItem(hListBox, "crayon", hbmpCrayon); AddItem(hListBox, "marker", hbmpMarker); AddItem(hListBox, "pen", hbmpPen); AddItem(hListBox, "fork", hbmpFork); SetFocus(hListBox); SendMessage(hListBox, LB_SETCURSEL, 0, 0); return TRUE; case WM_MEASUREITEM:
lpmis = (LPMEASUREITEMSTRUCT) lParam; /* Set the height of the list box items. */ lpmis->itemHeight = 20; return TRUE; case WM_DRAWITEM: lpdis = (LPDRAWITEMSTRUCT) lParam; /* If there are no list box items, skip this message. */ if (lpdis->itemID == -1) { break; } /* * Draw the bitmap and text for the list box item. Draw a
* rectangle around the bitmap if it is selected. */ switch (lpdis->itemAction) { case ODA_SELECT: case ODA_DRAWENTIRE: /* Display the bitmap associated with the item. */ hbmpPicture = (HBITMAP) SendMessage(lpdis->hwndItem, LB_GETITEMDATA, lpdis->itemID, (LPARAM) 0); hdcMem = CreateCompatibleDC(lpdis->hDC);
hbmpOld = SelectObject(hdcMem, hbmpPicture); BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, lpdis->rcItem.right - lpdis->rcItem.left, lpdis->rcItem.bottom - lpdis->rcItem.top, hdcMem, 0, 0, SRCCOPY); /* Display the text associated with the item. */ SendMessage(lpdis->hwndItem, LB_GETTEXT,
lpdis->itemID, (LPARAM) tchBuffer); GetTextMetrics(lpdis->hDC, &tm); y = (lpdis->rcItem.bottom + lpdis->rcItem.top - tm.tmHeight) / 2; TextOut(lpdis->hDC, XBITMAP + 6, y, tchBuffer, strlen(tchBuffer)); SelectObject(hdcMem, hbmpOld);
DeleteDC(hdcMem); /* Is the item selected? */ if (lpdis->itemState & ODS_SELECTED) { /* * Set RECT coordinates to surround only the * bitmap. */ rcBitmap.left = lpdis->rcItem.left; rcBitmap.top = lpdis->rcItem.top; rcBitmap.right = lpdis->rcItem.left + XBITMAP;
rcBitmap.bottom = lpdis->rcItem.top + YBITMAP; /* * Draw a rectangle around bitmap to indicate * the selection. */ DrawFocusRect(lpdis->hDC, &rcBitmap); } break; case ODA_FOCUS: /* * Do not process focus changes. The focus caret
* (outline rectangle) indicates the selection. * The Which one? (IDOK) button indicates the final * selection. */ break; } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: /* Get the selected item's text. */ nItem = SendMessage(GetDlgItem(hDlg, IDL_STUFF),
LB_GETCURSEL, 0, (LPARAM) 0); hbmp = SendMessage(GetDlgItem(hDlg, IDL_STUFF), LB_GETITEMDATA, nItem, 0); /* * If the item is not the correct answer, tell the * user to try again. * * If the item is the correct answer, congratulate * the user and destroy the dialog box.
*/ if (hbmp != hbmpFork) { MessageBox(hDlg, "Try again!", "Oops.", MB_OK); return FALSE; } else { MessageBox(hDlg, "You're right!", "Congratulations.", MB_OK); /* Fall through. */ } case IDCANCEL: /* Destroy the dialog box. */
EndDialog(hDlg, TRUE); return TRUE; default: return FALSE; } case WM_DESTROY: /* Free any resources used by the bitmaps. */ DeleteObject(hbmpPencil); DeleteObject(hbmpCrayon); DeleteObject(hbmpMarker); DeleteObject(hbmpPen); DeleteObject(hbmpFork); return TRUE;
default: return FALSE; } return FALSE; }
| Пригласи друзей и счет твоего мобильника всегда будет положительным! |
| Пригласи друзей и счет твоего мобильника всегда будет положительным! |
Ящик Списка Создания Owner-Drawn
Следующий пример показывает как, чтобы делать ящиком списка, который содержит пять сделанных пунктов владельца: четыре чертежа принадлежности и вилка. Каждый пункт списка появляется как побитовое отображение сопровождалось именем объекта. Кнопка подсказывает потребителя, чтобы выбираться один пункт, который - не любить другие. Выбор кнопки с выбранной вилкой отображает "Вы правы!" сообщение и закрывает диалоговый ящик. Выбор кнопки с любым другим выбранным пунктом списка отображает "Попытку снова!" сообщение.
Ящик списка имеет LBS_OWNERDRAW и стили LBS_HASSTRINGS, дополнительно к стилям ящика стандартного списка. Код инициализирует ящик списка посылая сообщение LB_ADDSTRING, чтобы устанавливать текст, затем посылает сообщение LB_SETITEMDATA, чтобы соединять побитовое отображение с каждым пунктом ящика списка. Код также устанавливает высоту каждого пункта ящика списка обрабатывая сообщение WM_MEASUREITEM и делает текстом и побитовым отображением для каждого пункта обрабатывая сообщение WM_DRAWITEM.
#define XBITMAP 80 #define YBITMAP 20 #define БУФЕР MAX_PATH HBITMAP hbmpPencil, hbmpCrayon, hbmpMarker, hbmpPen, hbmpFork; hbmpPicture HBITMAP, hbmpOld; пустота AddItem(HWND hwnd, LPSTR lpstr, HBITMAP hbmp) { int nItem; nItem = SendMessage(hwndList, LB_ADDSTRING, 0, lpstr); SendMessage(hwndList, LB_SETITEMDATA, nItem, hbmp); } DWORD APIENTRY DlgDrawProc( HWND hDlg, /* РУЧКА окна диалогового ящика */
СООБЩЕНИЕ UINT, /* тип сообщения */ UINT wParam, /* сообщеняя-специфическая информация */ ДОЛГО (ДЛИНОЙ) lParam) { int nItem; TCHAR tchBuffer[BUFFER]; HBITMAP hbmp; HWND hListBox; tm TEXTMETRIC; int y; HDC hdcMem; lpmis LPMEASUREITEMSTRUCT; lpdis LPDRAWITEMSTRUCT; RECT rcBitmap; ключ (сообщение) { случай WM_INITDIALOG: /* Загрузка bitmaps. */
hbmpPencil = LoadBitmap(hinst, MAKEINTRESOURCE(700)); hbmpCrayon = LoadBitmap(hinst, MAKEINTRESOURCE(701)); hbmpMarker = LoadBitmap(hinst, MAKEINTRESOURCE(702)); hbmpPen = LoadBitmap(hinst, MAKEINTRESOURCE(703)); hbmpFork = LoadBitmap(hinst, MAKEINTRESOURCE(704)); /* Извлеките блока списка handle. */ hListBox = GetDlgItem(hDlg, IDL_STUFF); /* * Инициализируйте текст блока списка и соединяйте побитовое отображение
* с каждым пунктом блока списка. */ AddItem(hListBox, "КАРАНДАШ", hbmpPencil); AddItem(hListBox, "ПАСТЕЛЬ", hbmpCrayon); AddItem(hListBox, "МАРКЕР", hbmpMarker); AddItem(hListBox, "РУЧКА", hbmpPen); AddItem(hListBox, "ВИЛКА", hbmpFork); SetFocus(hListBox); SendMessage(hListBox, LB_SETCURSEL, 0, 0); возвращайтесь ВЕРНО; случай WM_MEASUREITEM:
lpmis = (LPMEASUREITEMSTRUCT) lParam; /* Установите высоту блока списка items. */ lpmis->itemHeight = 20; возвращайтесь ВЕРНО; случай WM_DRAWITEM: lpdis = (LPDRAWITEMSTRUCT) lParam; /* Если нет пунктов блока списка, пропустите этот message. */ если (lpdis->itemID == -1) { прерывание; } /* * Сделайте побитовым отображением и текстом для пункта блока списка. Сделайте a
* прямоугольник вокруг побитового отображения если выбрано. */ ключ (lpdis->itemAction) { случай ODA_SELECT: случай ODA_DRAWENTIRE: /* Отобразите побитовое отображение связанное пунктом. */ hbmpPicture = (HBITMAP) SendMessage(lpdis->hwndItem, LB_GETITEMDATA, lpdis->itemID, (LPARAM) 0); hdcMem = CreateCompatibleDC(lpdis->hDC);
hbmpOld = SelectObject(hdcMem, hbmpPicture); BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, lpdis->rcItem.right - lpdis->rcItem.left, lpdis->rcItem.bottom - lpdis->rcItem.top, hdcMem, 0, 0, SRCCOPY); /* Отобразите текст связанный item. */ SendMessage(lpdis->hwndItem, LB_GETTEXT,
lpdis->itemID, (LPARAM) tchBuffer); GetTextMetrics(lpdis->hDC, &tm); y = (lpdis->rcItem.bottom + lpdis->rcItem.top - tm.tmHeight) / 2; TextOut(lpdis->hDC, XBITMAP + 6, y, tchBuffer, strlen(tchBuffer)); SelectObject(hdcMem, hbmpOld);
DeleteDC(hdcMem); /* Пункт выбраться? */ если (lpdis->itemState & ODS_SELECTED) { /* * Установите координаты RECT, чтобы окружать только the * побитовое отображение. */ rcBitmap.left = lpdis->rcItem.left; rcBitmap.top = lpdis->rcItem.top; rcBitmap.right = lpdis->rcItem.left + XBITMAP;
rcBitmap.bottom = lpdis->rcItem.top + YBITMAP; /* * Сделайте прямоугольником вокруг побитового отображения, чтобы указываться * выбор. */ DrawFocusRect(lpdis->hDC, &rcBitmap); } прерывание; случай ODA_FOCUS: /* * Не обрабатывайте изменения фокуса. Символ ^ фокуса
* (структурированный прямоугольник), указывает выбор. * Какое один? КНОПКА (IDOK) указывает финал * выбор. */ прерывание; } возвращайтесь ВЕРНО; случай WM_COMMAND: ключ (LOWORD(wParam)) { случай IDOK: /* Получите выбранный пункт text. */ nItem = SendMessage(GetDlgItem(hDlg, IDL_STUFF),
LB_GETCURSEL, 0, (LPARAM) 0); hbmp = SendMessage(GetDlgItem(hDlg, IDL_STUFF), LB_GETITEMDATA, nItem, 0); /* * Если пункт не является правильным ответом, сообщите the * пользователь, чтобы пытаться снова. * * Если пункт является правильным ответом, поздравьте * пользователь и уничтожает диалогового блока.
*/ если (hbmp != hbmpFork) { MessageBox(hDlg, "Попытка снова!", "Oops.", MB_OK); обратная ЛОЖЬ; } еще { MessageBox(hDlg, "ВЫ правы!", "Поздравления.", MB_OK); /* Падение through. */ } случай IDCANCEL: /* Уничтожьте диалогового блока. */
EndDialog(hDlg, TRUE); возвращайтесь ВЕРНО; умолчание: обратная ЛОЖЬ; } случай WM_DESTROY: /* Освободите любые ресурсы использованные bitmaps. */ DeleteObject(hbmpPencil); DeleteObject(hbmpCrayon); DeleteObject(hbmpMarker); DeleteObject(hbmpPen); DeleteObject(hbmpFork); возвращайтесь ВЕРНО;
умолчание: обратная ЛОЖЬ; } обратная ЛОЖЬ; }
|
|
|
|
| |