Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.140.242.165] |
|
Сообщ.
#1
,
|
|
|
Доброго времени суток уважаемые форумчане. Возникла необходимость написать TreeView на чистом WinAPI, стандартные макросы тоже использовать не стал... Написал небольшую программку для тестирования.
"Исходный код:" #include "stdafx.h" #include <commctrl.h> #include <stdio.h> #define MY_BTN1 101 #define MY_BTN2 102 #pragma comment(lib, "comctl32.lib") LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); HWND hwnd, hTree, hBtn1, hBtn2, hEdit; char szClassName[ ] = "TestTreeView"; HINSTANCE hInstance = GetModuleHandle(NULL); int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { MSG messages; WNDCLASSEX wcl; InitCommonControls(); wcl.hInstance = hThisInstance; wcl.lpszClassName = szClassName; wcl.lpfnWndProc = WindowProcedure; wcl.style = CS_DBLCLKS; wcl.cbSize = sizeof (WNDCLASSEX); wcl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wcl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wcl.hCursor = LoadCursor (NULL, IDC_ARROW); wcl.lpszMenuName = NULL; wcl.cbClsExtra = 0; wcl.cbWndExtra = 0; wcl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; if (!RegisterClassEx (&wcl)){ return 0; } hwnd = CreateWindowEx (0, szClassName,"TestTreeView",WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,CW_USEDEFAULT,CW_USEDEFAULT,450,350,HWND_DESKTOP,NULL,hThisInstance,NULL); ShowWindow (hwnd, nFunsterStil); while (GetMessage (&messages, NULL, 0, 0)) { TranslateMessage(&messages); DispatchMessage(&messages); } return messages.wParam; } LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static TVINSERTSTRUCT tvins; static TVITEM tvi; static char szItemText[128] = ""; switch (message) { case WM_CREATE: { hBtn1 = CreateWindowEx(0, "button", "ADD ROOT ITEM", WS_CHILD | WS_VISIBLE, 280, 50, 150, 30, hwnd, (HMENU)MY_BTN1, hInstance, NULL); SendMessage(hBtn1, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0); hBtn2 = CreateWindowEx(0, "button", "ADD TO ROOT ITEM", WS_CHILD | WS_VISIBLE, 280, 100, 150, 30, hwnd, (HMENU)MY_BTN2, hInstance, NULL); SendMessage(hBtn2, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0); hTree = CreateWindowEx(0, WC_TREEVIEW, 0, WS_CHILD | WS_VISIBLE | WS_BORDER | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS, 10, 45, 250, 250, hwnd, NULL, hInstance, NULL); hEdit = CreateWindowEx(0, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER, 10, 20, 420, 20, hwnd, NULL, hInstance, NULL); SendMessage(hEdit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0); SetFocus (hEdit); } break; case WM_COMMAND: switch(LOWORD(wParam)) { case MY_BTN1: { //Считываю текст из EditBox'a GetWindowText (hEdit, szItemText, 1024); tvi.mask = TVIF_TEXT | TVIF_PARAM; tvi.pszText = szItemText; tvi.cchTextMax = strlen(szItemText); tvins.item = tvi; tvins.hInsertAfter = (HTREEITEM)TVI_FIRST; tvins.hParent = TVI_ROOT; //Добавляю ROOT-элемент SendMessage(hTree, TVM_INSERTITEM, 0, (LPARAM)&tvins); //Выполняю сортировку пунктов TreeView SendMessage(hTree, TVM_SORTCHILDREN, 0, 0); } break; case MY_BTN2: { //Считываю текст из EditBox'a GetWindowText (hEdit, szItemText, 1024); tvi.mask = TVIF_TEXT | TVIF_PARAM; tvi.pszText = szItemText; tvi.cchTextMax = strlen(szItemText); tvins.item = tvi; //Получаю HTREEITEM ROOT-элемента куда собираюсь добавить новый дочерний пункт tvins.hParent = (HTREEITEM)SendMessage(hTree,TVM_GETNEXTITEM,(WPARAM)(UINT)TVGN_CARET,NULL); //Добавляю пункт SendMessage(hTree, TVM_INSERTITEM, 0, (LPARAM)&tvins); } break; } break; case WM_DESTROY: PostQuitMessage (0); break; default: return DefWindowProc (hwnd, message, wParam, lParam); } return 0; } Корневые пункты в TreeView добавляются без проблем, а вот при добавлении подпунктов в корневой, добавляемый пункт сразу после нажатия на кнопку не отображается, но если щелкнуть по TreeView, добавленные подпункты (в смысле плюсик) появляются... Такая проблема Сам пол дня искал ошибку, но так и не смог разобраться, где косячок закрался... Может кто-нибудь сталкивался, буду Вам очень признателен за помощь. Спасибо. Добавлено Решил проблему добавлением SetFocus (hTree); после добавления подпункта и выполнения сортировки пунктов, но хотелось бы разобраться с ошибкой принципиально, а не при помощи "изоленты"))) |
Сообщ.
#2
,
|
|
|
Цитата sydep @ ..хотелось бы разобраться с ошибкой принципиально, а не при помощи "изоленты"))) Трудно сказать, почему так получается. Возможно такое объяснение: Можно предположить, что после изменений надо перерисовать окно контрола. Если пунктов надо добавить много, тогда будет много перерисовок, хотя достаточно одной - после всех изменений. Поэтому выполнение перерисовки остаётся как отдельная акция за программой. "SetFocus", вероятно, приводит к перерисовке контрола. Попробуй заменить "SetFocus" функцией ::InvalidateRect(hTree,NULL,TRUE); |
Сообщ.
#3
,
|
|
|
А если
RedrawWindow(hTree, NULL, NULL, RDW_INTERNALPAINT); |
Сообщ.
#4
,
|
|
|
ЫукпШ
спасибо, InvalidateRect сработала... более качественная "изолента" +1 Реально очень странно, вроде все делаю по как по матчасти, а получается... Видимо какой то косяк в процедуре обработки сообщений от главного окна. Mr.Brooks RedrawWindow(hTree, NULL, NULL, RDW_INTERNALPAINT); работает только с параметром RDW_INVALIDATE |