Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Создание Status Bar


Автор: MenSem 9.8.2008, 11:03
del

Автор: mekhanikus 9.8.2008, 13:15
Код

#include <commctrl.h>
 Делал?

Автор: MenSem 9.8.2008, 14:16
del

Автор: 586 9.8.2008, 14:59
Читай MSDN внимательнее:
Цитата(MSDN)
Minimum DLL Version comctl32.dll 
Header commctrl.h 
Import library comctl32.lib 
Minimum operating systems Windows NT 3.51, Windows 95 

Код
#pragma comment (lib, "comctl32.lib")

Автор: MenSem 9.8.2008, 15:12
del
 

Автор: MenSem 10.8.2008, 15:40
del

Автор: 586 10.8.2008, 17:15
Телепаты в отпуске. Выкладывай код, как создаёшь statusbar, и что за ошибка.

Автор: MenSem 10.8.2008, 18:37
del

Автор: MenSem 10.8.2008, 18:58
del

Автор: MenSem 10.8.2008, 21:08
del

Автор: Dem_max 11.8.2008, 04:32
Попробуй так
Код

#include <commctrl.h>
#pragma comment(lib, "comctl32.lib")

   INITCOMMONCONTROLSEX icex;
   icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
   icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES;
   InitCommonControlsEx(&icex);

 
 hWndStatusBar = CreateStatusWindow( WS_CHILD | WS_VISIBLE,
                                       NULL,
                                       hWndMain,
                                       ID_STATUS_BAR);

Автор: MenSem 11.8.2008, 10:19
del

Автор: MenSem 11.8.2008, 13:00
del

Автор: Ant 12.8.2008, 08:38
Можно

Автор: MenSem 12.8.2008, 09:04
del

Автор: 586 12.8.2008, 10:08
Цитата(MenSem @  11.8.2008,  14:00 Найти цитируемый пост)
А можно сделать так, что бы автоматом в строке состояние отображался текст, при наведении курсора на пункт меню, заданный в свойстве меню promt , как в MFC?

Это придётся делать вручную, обрабатывая сообщение WM_MENUSELECT.
Цитата(MenSem @  12.8.2008,  10:04 Найти цитируемый пост)
И еще вопрос: почему при изменении размеров главного окна status bar остается на прежнем месте? (на сообщение WM_SIZE не реагирует) 

При изменении размера окна отправь statusbar'у сообщение:
Код
SendMessage(hStatusBar, WM_SIZE, 0, 0);


Автор: MenSem 12.8.2008, 10:42
del

Автор: 586 12.8.2008, 11:10
Цитата(MenSem @  12.8.2008,  11:42 Найти цитируемый пост)
Можно чуть по подробней?

http://msdn.microsoft.com/en-us/library/ms646352(VS.85).aspx
Как работает это сообщение можешь в Spy++ посмотреть.


Цитата(MenSem @  12.8.2008,  11:42 Найти цитируемый пост)
hWndSbar - дескриптор status bar

Дескриптор верный? Проверял в отладчике значение переменной hWndSbar? Какая ОС?

Автор: MenSem 12.8.2008, 11:26
del

Автор: 586 12.8.2008, 12:16
В MSDN сказано, что такое сообщение можно посылать статусбару.
Цитата(http://msdn.microsoft.com/en-us/library/bb760728(VS.85).aspx)
The window procedure automatically adjusts the size of the status bar whenever it receives a WM_SIZE message. Typically, when the size of the parent window changes, the parent sends a WM_SIZE message to the status bar.

У меня всё работает. Имхо, у тебя где-то проблема.

Автор: MenSem 12.8.2008, 12:28
del

Автор: MenSem 12.8.2008, 12:45
del

Автор: 586 12.8.2008, 13:07
Цитата(MenSem @  12.8.2008,  13:45 Найти цитируемый пост)
Вообщем дошло в чем ошибка.

И в чём же была ошибка?

Автор: MenSem 12.8.2008, 15:30
del

Автор: MenSem 13.8.2008, 14:35
del

Автор: MenSem 14.8.2008, 15:08
del

Автор: mekhanikus 15.8.2008, 11:37
Цитата(MenSem @ 13.8.2008,  14:35)
Я так понимаю нужно ограничивать размеры MDICLIENT  что бы дочернии форы не залазили сверху на статус бар и сворачивались выше сатус бара?

Попробовал, действительно косяк, у меня тоже чилдрены закрывают статус бар или прячутся за него.
Как это побороть пока не знаю.
Может отлавливать момент сворачивания-разворачивания чилдов и направлять их в нужное русло?

Автор: GremlinProg 15.8.2008, 13:01
Цитата(MenSem @  13.8.2008,  16:35 Найти цитируемый пост)
Я так понимаю нужно ограничивать размеры MDICLIENT  что бы дочернии форы не залазили сверху на статус бар и сворачивались выше сатус бара?

попробуй создать статус не на клиенте, а на фрейме,
но при этом, на WM_SIZE фрейма необходимо позиционировать клиент вручную

Добавлено через 1 минуту и 32 секунды
лучше вообще все контролы вручную позичионировать

Автор: Dem_max 15.8.2008, 13:51
Для ограничения размеров окна MDI попробуй вот это, хотя я ниразу для MDI не пользовался
Цитата

The WM_GETMINMAXINFO message is sent to a window when the size or position of the window is about to change. An application can use this message to override the window's default maximized size and position, or its default minimum or maximum tracking size. 

WM_GETMINMAXINFO  
lpmmi = (LPMINMAXINFO) lParam; // address of structure 


типа так:
  LPMINMAXINFO mmi;
   mmi->ptMinTrackSize.x=380;
   mmi->ptMinTrackSize.y=400;

Автор: MenSem 15.8.2008, 14:51
del

Автор: GremlinProg 15.8.2008, 14:59
Dem_max, речь не о ограничении внешних размеров фрейма, читай вопрос внимательно:

Цитата(MenSem @  13.8.2008,  16:35 Найти цитируемый пост)
Я так понимаю нужно ограничивать размеры MDICLIENT  что бы дочернии форы не залазили сверху на статус бар и сворачивались выше сатус бара?

MDICLIENT - дочернее, а не перекрытое окно

MenSem,  поскольку статус - контрол простой до безобразия, в него практически никогда не суют контролы, есть еще более корректный и облегченный способ создания статус бара - это резервирование неклиентской области под статус в WM_NCCALCSIZE и рисование в нем чего-либо в WM_NCPAINT, тогда дополнительно ничего позиционировать не придется, т.к. статус уже не будет отображаться в клиентской области (не будет так же и лишней нагрузки - окна статус бара (по моему, этот контрол вообще создан только для очень ленивых программистов)

на форуме и в MSDN достаточно подробной информации на эту тему, нужно только поискать

Автор: MenSem 15.8.2008, 18:46
del

Автор: GremlinProg 15.8.2008, 19:39
Цитата(MenSem @  15.8.2008,  20:46 Найти цитируемый пост)
+ еще косяк: когда дочерняя форма максимизируется, она закрывет статус бар, т.е. статус бар полностью пропадает.

см. пред-предыдущий пост, я уже писал как с этим бороться

процедура фрейма:
Код

case WM_NCCALCSIZE:{
    RECT&ncrc     = *(RECT*)lParam;
    RECT org     = ncrc;
    //
    ::DefWindowProc(...);
    //
    status_rect        = ncrc;
    status_rect.top    = status_rect.bottom - status_bar_height;
    //
    ::SubtractRect(&ncrc,&ncrc,&status_rect);
    ::OffsetRect(&status_rect,-org.left,-org.top);
    //
    break;
}
case WM_NCPAINT:{
    HDC hdc    = ::GetWindowDC(hWnd);
    //
    ::DrawEdge(hdc,&status_rect,EDGE_RAISED,BF_RECT|BF_MIDDLE);
    //
    ::ReleaseDC(hWnd,hdc);
    break;
}

здесь статус рисует всего лишь одна функция ::DrawEdge(...), если хочешь разнообразия, смени её на то, что нужно

точно так же можно сделать и тулбар, но там сложнее, это не уложится ни в какой топик форума,
принципы создания контролов в неклиентской области я уже не раз расписывал

PS: код не проверял, но пока вроде ошибок не вижу, пиши, если что

Автор: MenSem 15.8.2008, 19:46
del

Автор: GremlinProg 15.8.2008, 19:58
status_bar_height - высота статус бара,
status_rect - прямоугольник статус бара в неклиентской области


задать изначально нужно только status_bar_height, остальное вычислится самостоятельно

Автор: MenSem 15.8.2008, 20:26
del

Автор: GremlinProg 15.8.2008, 20:33
в WM_NCPAINT ::DefWindowProc(...) вызови вернее DefFrameProc

Добавлено через 1 минуту и 56 секунд
стандартная обработка в любом случае должна быть, я ж ни где не писал return

Добавлено через 3 минуты
хотя в WM_NCCALCSIZE можно заменить break return'ом, т.к. используется префиксная форма

Автор: MenSem 15.8.2008, 21:02
del

Автор: GremlinProg 15.8.2008, 21:36
) посмотри внимательно на код, смотри, чтобы вызовы DefFrameProc не дублировались
по скрину хорошо видно, что DefFrameProc вызван 2 раза, что привело к двойному вычету границ
Цитата(GremlinProg @  15.8.2008,  22:33 Найти цитируемый пост)
хотя в WM_NCCALCSIZE можно заменить break return'ом, т.к. используется префиксная форма

"можно" заменить на "нужно"

Автор: MenSem 16.8.2008, 08:16
del

Автор: GremlinProg 16.8.2008, 12:25
Цитата(MenSem @  15.8.2008,  22:26 Найти цитируемый пост)
Меню ни одно не открывается, сразу ошибка

это скорее всего связано с чем-то другим, показывай процедуру окна

Автор: MenSem 16.8.2008, 13:12
del

Автор: GremlinProg 16.8.2008, 13:48
на сообщение WM_NCCALCSIZE lParam всегда указывает как минимум на RECT, следовательно ошибка происходит на другое сообщение, убедись в том, что перед case WM_NCCALCSIZE стоит break

здесь речь идет о создании статусбара, а не о том, где у тебя там синтаксические ошибки
мы ведь здесь не можем исправлять их телепатически

раз ты не хочешь показывать код, значит исправляй все сам

Добавлено через 4 минуты и 23 секунды
статус бар и не будет рисоваться, пока все ошибки не будут исправлены

Автор: MenSem 16.8.2008, 14:14
del

Автор: GremlinProg 16.8.2008, 19:19
думай, решай, я уже говорил, есть простой способ решить проблему: выложить код

Автор: MenSem 16.8.2008, 19:26
del

Автор: GremlinProg 16.8.2008, 21:10
мда уж, подходящего смайла винград просто не знает

хороший код, красивый код, только зачем он тут?

никакого отношения к процедуре окна фрейма он не имеет
к тому же, отдельное окно статус бара уже давным давно не нужно,
оно у тебя реализовано в неклиентской области двумя перехватами сообщений

Автор: MenSem 16.8.2008, 21:28
del

Автор: GremlinProg 16.8.2008, 21:31
если хочешь найти ошибку - вся

Добавлено через 2 минуты и 23 секунды
ну пошли её приватным сообщением, если уж так страшно

Автор: MenSem 16.8.2008, 21:35
del

Автор: GremlinProg 16.8.2008, 21:40
RECT status_rect;

вынеси это определение глобально, вне процедуры окна, а локальные дубли убери

Добавлено через 26 секунд
это основная ошибка

Автор: MenSem 16.8.2008, 21:41
del

Автор: GremlinProg 16.8.2008, 21:44
советую привести процедуру к виду:
Код

switch(message){
   case :{}
   case :{}
   case :{}
}
return ::DefFrameProc(...)

сейчас она у тебя такого вида:
Код

switch(message){
   case :{}
   case :{}
   case :{}
  default:
     return::DefFrameProc(...)
}
return 0;

Добавлено @ 21:45
Цитата(MenSem @  16.8.2008,  23:41 Найти цитируемый пост)
Ну мог бы сразу сказать.

ну извини, не телепат

это объявление ты сам сделал, я его не писал

Автор: MenSem 16.8.2008, 21:47
del

Автор: GremlinProg 16.8.2008, 21:50
ну вот, это твой статус бар, сейчас он выглядит как кнопка, можешь стандартный сделать:
Код

::DrawEdge(hdc,&status_rect,EDGE_RAISED,BF_TOP|BF_MIDDLE);


Добавлено @ 21:55
теперь можешь любой текст вывести, такм же, в сообщении WM_NCPAINT, после DrawEdge
Код

RECT rt;
::CopyRect(&rt,&status_rect);
::InflateRect(&rt,-1,-1);
::DrawText(hdc,"бла-бла",-1,&rt,DT_SINGLELINE | DT_VCENTER | DT_LEFT);

Автор: MenSem 16.8.2008, 21:56
del

Автор: GremlinProg 16.8.2008, 22:01
если нужен SIZE GRIP, то добавь такой код:
Код

RECT sg;
::CopyRect(&sg,&status_rect);
sg.left = sg.right - sg.bottom + sg.top;
::DrawFrameControl(hdc,&rc,DFC_SCROLL|DFCS_SCROLLSIZEGRIP,0);


Добавлено через 50 секунд
текст? смотри на пост выше

Добавлено через 3 минуты и 28 секунд
рисуешь, как хочешь, это уже независимая область, с клиентом он не соприкасается

ресурсов для статусбара нет

Автор: MenSem 16.8.2008, 22:09
del

Автор: GremlinProg 16.8.2008, 22:14
поставь ::SetBkMode(hdc,TRANSPARENT); перед DrawText

Автор: MenSem 16.8.2008, 22:27
del

Автор: GremlinProg 16.8.2008, 22:37
ну, остальное уже сам, статус баром эта тема и должна закончиться

Автор: MenSem 16.8.2008, 22:38
del

Автор: Dem_max 19.8.2008, 18:51
Чет у вас сложно все со статус баром
вот код
Код

   hWndStatusBar = CreateStatusWindow( WS_CHILD | WS_VISIBLE,
                                       NULL,
                                       hWndMain,
                                       ID_STATUS_BAR);

   int pParts[3];   
   pParts[0]=200;
   pParts[1]=400;
   pParts[2]=1000;
   SendMessage(hWndStatusBar,SB_SETPARTS,3,(LPARAM)pParts);
   SendMessage(hWndStatusBar,SB_SETMINHEIGHT,10,0);

   HICON im1 = LoadImage(hInstance,MAKEINTRESOURCE(ID_ICON7), IMAGE_ICON,2,22, LR_DEFAULTCOLOR);
   SendMessage(hWndStatusBar,SB_SETICON,0,(LPARAM)wc.hIconSm);//im);
   SendMessage(hWndStatusBar, SB_SETTEXT,0| SBT_NOBORDERS,(LONG)"RadioButton 111");
   SendMessage(hWndStatusBar,SB_SETICON,1,(LPARAM)im1);
   SendMessage(hWndStatusBar,SB_SETTEXT,1 | SBT_NOBORDERS ,0);
   SendMessage(hWndStatusBar,SB_SETICON,2,(LPARAM)im1);
   SendMessage(hWndStatusBar,SB_SETTEXT,2| SBT_NOBORDERS,(LONG)"RadioButton 3");
   MoveWindow(hWndStatusBar, 0, 0, 0, 0, TRUE);

   RECT pr;
   SendMessage(hWndStatusBar, SB_GETRECT,1,(LPARAM) (LPRECT)&pr);

    hWndProgressBar = CreateWindowEx(
                NULL,
                "msctls_progress32",
                NULL,
                WS_VISIBLE | WS_CHILD,
                pr.left+7, pr.top+2, pr.right-207, pr.bottom-6, 
                hWndStatusBar,
                (HMENU)ID_PROGRESS_BAR,
                hInstance,
                NULL ); 
   SendMessage(hWndProgressBar, PBM_SETSTEP,10,0);
   SendMessage(hWndProgressBar, PBM_SETPOS,50,0); 



Результат ниже на картинке 
http://ipicture.ru/

Автор: MenSem 23.8.2008, 14:16
del

Автор: MenSem 30.8.2008, 18:20
del

Автор: 586 30.8.2008, 18:52
ShowWindow SW_SHOW / SW_HIDE

Автор: Dem_max 30.8.2008, 19:04
ShowWindow(hWndStatusBar ,SW_HIDE);
ShowWindow(hWndStatusBar ,SW_SHOW);

Автор: GremlinProg 30.8.2008, 19:11
Цитата(MenSem @  30.8.2008,  20:20 Найти цитируемый пост)
А как прятать и обратно показывать статус бар?

нужно просто глобальный флаг завести, например
Код

BOOL status_visible;


в WM_NCCALCSIZE этот флаг проверять:
  если флаг поднят(status_visible == TRUE), то в WM_NCCALCSIZE ncrc модифицировать как положено,
  если флаг опущен(status_visible == FALSE), то ncrc не должен быть затронут, т.е. SubtractRect вызывать не нужно (в принципе и status_rect расчитывать так же не надо)

при рисовании в WM_NCPAINT смотрим так же на этот флаг:
  если флаг поднят, то рисуем статус бар в status_rect
  если флаг опущен, то ни чего не рисуем

теперь, чтобы скрыть статус, нужно сделать 2 телодвижения:
Код

status_visible = FALSE;
SetWindowPos(hWnd,0,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED|SWP_NOZORDER);


Добавлено @ 19:11
показать - аналогично:
Код

status_visible = TRUE;
SetWindowPos(hWnd,0,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED|SWP_NOZORDER);


Добавлено @ 19:12
понятно, что изначально status_visible дожен быть поднят:
Код

BOOL status_visible = TRUE;

Автор: MenSem 6.9.2008, 07:08
del

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)