Знаю, что в MFC есть такой класс.
А на winapi что нибудь подобное сделать можно? ( в смысле есть что нибудь подобное, что можно применить к окнам диалога и вообще к любым окнам)
(для некоторых, кто не в курсе английского названия поясняю: это вертикальная или горизонтальная полоска, если её двигать, то изменяется размер радяом стоящих элементов. Например regedit в винде-в пуске-выплнить)
Здравствуйте, Calc, Вы писали:
C>Знаю, что в MFC есть такой класс. C>А на winapi что нибудь подобное сделать можно? ( в смысле есть что нибудь подобное, что можно применить к окнам диалога и вообще к любым окнам)
C>(для некоторых, кто не в курсе английского названия поясняю: это вертикальная или горизонтальная полоска, если её двигать, то изменяется размер радяом стоящих элементов. Например regedit в винде-в пуске-выплнить)
C>спасибо!
В winapi я искал но не нашел каких либо функция для создания и работы с Splitter-ом.
я использовал WTL (CSplitterWindow m_vSplit).
Здравствуйте, Calc, Вы писали:
C>Знаю, что в MFC есть такой класс. C>А на winapi что нибудь подобное сделать можно? ( в смысле есть что нибудь подобное, что можно применить к окнам диалога и вообще к любым окнам)
C>(для некоторых, кто не в курсе английского названия поясняю: это вертикальная или горизонтальная полоска, если её двигать, то изменяется размер радяом стоящих элементов. Например regedit в винде-в пуске-выплнить)
C>спасибо!
Если вы посмотрите на реализацию splitter в ATL. то увидете, что они сами его рисуют. Из этого я заключаю,
что такого контрола нет. (м.б. я и не прав...)
Здравствуйте, Lonely Dog, Вы писали:
LD>Если вы посмотрите на реализацию splitter в ATL. то увидете, что они сами его рисуют. Из этого я заключаю, LD>что такого контрола нет. (м.б. я и не прав...)
Здравствуйте, Calc, Вы писали:
LD>>Если вы посмотрите на реализацию splitter в ATL. то увидете, что они сами его рисуют. Из этого я заключаю, LD>>что такого контрола нет. (м.б. я и не прав...)
C>спасибо! C>Буду сам писать
А что там писать? Ну сделай два окна рядом, и обрабатывай мышиные события в области между ними, соответственно меняя их размеры и обрабатывая сообщения WM_SIZE, WM_SIZING...
Здравствуйте, Demiurg, Вы писали:
D>Здравствуйте, Calc, Вы писали:
D> А что там писать? Ну сделай два окна рядом, и обрабатывай мышиные события в области между ними, соответственно меняя их размеры и обрабатывая сообщения WM_SIZE, WM_SIZING...
А вот и флуд пошёл.
Я уж сам догадался.
Просто это мой первый опыт будет. Начинаю писать первую программу под вин.
Здравствуйте, Calc, Вы писали:
D>> А что там писать? Ну сделай два окна рядом, и обрабатывай мышиные события в области между ними, соответственно меняя их размеры и обрабатывая сообщения WM_SIZE, WM_SIZING...
C>А вот и флуд пошёл. C>Я уж сам догадался.
Да какой уж там флуд?? Это первое, что пришло мне в голову, возможно не самый лучший вариант...
C>Просто это мой первый опыт будет. Начинаю писать первую программу под вин.
Здравствуйте, Calc, Вы писали:
C>(для некоторых, кто не в курсе английского названия поясняю: это вертикальная или горизонтальная полоска, если её двигать, то изменяется размер радяом стоящих элементов. Например regedit в винде-в пуске-выплнить)
Здравствуйте, Demiurg, Вы писали:
D> Получилось сплиттер сделать?
Пока нет. (ещё не пробовал)
Застрял на этом:
У меня в роли главного окна выступает диалог.
На нём есть Tree Control и List Control.
Делаю, чтоб они меняли свои размеры при изменении размеров диалога:
void Dlg_OnSize(HWND hwnd, UINT state, int cx, int cy)
{
RECT rectClient;
GetClientRect(hwnd, &rectClient);
MoveWindow(GetDlgItem(hwnd, IDC_TREE), rectClient.left, rectClient.top,rectClient.right/2 - 2,rectClient.bottom, TRUE);
MoveWindow(GetDlgItem(hwnd, IDC_LIST), rectClient.right/2 + 2, rectClient.top,rectClient.right/2,rectClient.bottom, TRUE);
}
// + 2 и - 2 потом будут заменены на переменные или на одну переменную, в зависимости от реализации сплиттера.
Это обработка сообщения WM_SIZE.
Код работает, но вот при дизайне диалога я просто разбросал эти control в произвольном порядке и форме.
Теперь при запуске приложения, появляется диалоговое окно и внём как при дизайне всё разбросано.
Начинаю менять размеры и всё в порядке.
Сижу ломаю голову, как сделать тоже самое, но ещё до появления окна.
WM_INITDIALOG не подходит.
Посоветуйте, что нибудь.
Пробовал отправить сообщение WM_SIZE из сообщения WM_INITDIALOG, но помоему сообщение WM_INITDIALOG возникает ещё до создания окна, так что нет смысла посылать.
Ну хотя бы подскажите в каком сообщении можно это сделать.
Помоему короче и легче.
Доработать надо только:
При нажатии на мышь, курсор меняется на стандартную стрелку.
При наведении курсора предположем на левый край сплиттера и зажатии кнопки, а потом движении влево сообщение WM_MOUSEMOVE не генерируется и сплиттер не перемещается.
Думаю это можно доработать
1) WM_LMOUSEDOWN
2) WM_MOUSELEAVE
Вот ваш код:
//========================
case WM_LBUTTONDOWN:
split=true;
SetCapture(hMainW);
SetCursor(LoadCursor(NULL,IDC_SIZEWE));
return 0;
case WM_LBUTTONUP:
split=false;
ReleaseCapture();
return 0;
case WM_MOUSEMOVE:
SetCursor(LoadCursor(NULL,IDC_SIZEWE));
Splitter(lParam);
return 0;
//========================
Заметил такую вещь:
При генерации сообщения WM_LMOUSEDOWN у меня почемуто после этого не генерировалось сообщение WM_MOUSEMOVE
Вот ещё:
MoveWindow(hControl2, LOWORD(lParam)+3, y, pRECT.right, pRECT.bottom, TRUE);
При размере больше 3х курсор IDC_SIZEWE находиться не по середине сплиттера.
И ещё вопрос, только он по C++ а не по WinApi
Обязательно ли завершать функции типа void ключевым словом return; ?
WM_MOUSEMOVE посылается очень часто при движении мыши, а у Вас тут вызывается функция SetCapture каждый раз. Это может затормозить машину или ещё какая гадость случится.
C>Вот ваш код:
C>
C>Заметил такую вещь: C>При генерации сообщения WM_LMOUSEDOWN у меня почемуто после этого не генерировалось сообщение WM_MOUSEMOVE
Не знаю: у меня всё работало. У меня тоже было с одной стороны дерево а с другой лист, но не в диалоге. Я при WM_CREATE создавал окна там где надо а потом уже обрабатывал WM_SIZE всякий.
C>Вот ещё: C>
C>MoveWindow(hControl2, LOWORD(lParam)+3, y, pRECT.right, pRECT.bottom, TRUE);
C>
C>При размере больше 3х курсор IDC_SIZEWE находиться не по середине сплиттера.
На счёт всяких там пикселей не помню: делал подбором, и потом у меня там ещё тулбар и статусбар были, так что не знаю. Я выдрал из программы и на скорую руку убрал что не надо...
C>И ещё вопрос, только он по C++ а не по WinApi
C>Обязательно ли завершать функции типа void ключевым словом return; ?
Нет. Это тебе надо только для досрочного завершения. Типа, если в if`е.
C>Жду похожей критики в адрес моего кода.
Ну, небольшую ты получил.
Здравствуйте, KycoK, Вы писали:
KK>Здравствуйте, Calc, Вы писали: KK>Ну, небольшую ты получил.
Изменил код, получился как и ваш. Недостатки моей реализации исчезли.
//----------------
Вот фрагмент вашего кода:
case WM_MOUSEMOVE:
SetCursor(LoadCursor(NULL,IDC_SIZEWE));
Splitter(lParam);
return 0;
Вот мой:
case WM_MOUSEMOVE:
SetCursor(LoadCursor(NULL,IDC_SIZEWE));
if(split) Splitter(hwnd, lParam);
Помоему он лучше тем, что функция Splitter вызывается не каждый раз(что замедляет работу программы), а только тогда, когда нажата кнопка мыши.(в функции splitter отменена проверка перменной split)