Maks150988
Advanced Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Привет. Кто-нибудь может помочь с такой ситуацией? Нужно отображать панель меню в ребаре - наподобие проводника/интернет эксплорера/системных программ. Сделал так: загрузил ресурс диалога И добавил это окошко в банд ребара. Как через SetParent или через что это делается сделать полностью загруженное окно CHILD? Код: {} procedure CreateMenuRebarToolbar(hWnd: Thandle); var hMenuRebar: Thandle; TRebarRect: TRect; TRebarInfo: TRebarBandInfoW; hChildWind: Thandle; cxIdeal : Integer; cxIndex : Integer; szBtnText : WideString; begin hMenuRebar := CreateWindowExW(WS_EX_TOOLWINDOW, REBARCLASSNAME, nil, WS_VISIBLE or WS_BORDER or WS_CHILD or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or RBS_VARHEIGHT or RBS_BANDBORDERS or CCS_NODIVIDER, 0, 0, 0, 0, hWnd, ID_MENUEX_SYSREBAR, hInstance, nil); if (hMenuRebar <> 0) then begin hChildWind := CreateDialogW(hInstance, MAKEINTRESOURCEW(RC_DIALOG_MENUEX), 0, nil); if (hChildWind <> 0) then begin SetMenu(hChildWind, RebarMenu); GetWindowRect(hChildWind, TRebarRect); ZeroMemory(@TRebarInfo, SizeOf(TRebarInfo)); TRebarInfo.cbSize := SizeOf(TRebarBandInfoW); TRebarInfo.fMask := RBBIM_SIZE or RBBIM_CHILD or RBBIM_CHILDSIZE or RBBIM_STYLE; TRebarInfo.cxMinChild := TRebarRect.Right - TRebarRect.Left; TRebarInfo.cyMinChild := TRebarRect.Bottom - TRebarRect.Top + 2; TRebarInfo.cx := 100; TRebarInfo.fStyle := RBBS_CHILDEDGE or RBBS_NOGRIPPER or RBBS_GRIPPERALWAYS; TRebarInfo.wID := ID_SYSREBAR_MENUEX; TRebarInfo.hwndChild := hChildWind; SendMessage(hMenuRebar, RB_INSERTBAND, WPARAM(-1), LPARAM(@TRebarInfo)); end; hChildWind := CreateWindowExW(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, nil, WS_VISIBLE or WS_CHILD or CCS_NODIVIDER or CCS_NORESIZE or CCS_NOPARENTALIGN or TBSTYLE_FLAT or TBSTYLE_TOOLTIPS, 0, 0, 0, 0, hMenuRebar, ID_SYSREBAR_TOOLB, hInstance, nil); if (hChildWind <> 0) then begin GetWindowRect(hChildWind, TRebarRect); SendMessageW(hChildWind, TB_BUTTONSTRUCTSIZE, SizeOf(TTBBUTTON), 0); SendMessageW(hChildWind, TB_BUTTONCOUNT, 0, 0); SendMessageW(hChildWind, TB_ADDBUTTONS, Length(tbButtons), LPARAM(@tbButtons)); SendMessageW(hChildWind, TB_AUTOSIZE, 0, 0); tbBitmap.hInst := 0; tbBitmap.nID := ImageBmp; SendMessageW(hChildWind, TB_ADDBITMAP, Length(tbButtons), LPARAM(@tbBitmap)); szBtnText := 'Открыть файл'#0'Извлечь в...'#0'Поиск файлов'#0'Информация'#0'О программе'#0#0; //SendMessageW(hChildWind, TB_ADDSTRINGW, 0, LPARAM(szBtnText)); SendMessageW(hChildWind, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS or TBSTYLE_EX_MIXEDBUTTONS); cxIdeal := 0; for cxIndex := 0 to SendMessageW(hChildWind, TB_BUTTONCOUNT, 0, 0) - 1 do begin SendMessageW(hChildWind, TB_GETITEMRECT, WPARAM(cxIndex), LPARAM(@TRebarRect)); Inc(cxIdeal, (TRebarRect.Right - TRebarRect.Left)); end; ZeroMemory(@TRebarInfo, SizeOf(TRebarInfo)); TRebarInfo.cbSize := SizeOf(TRebarBandInfoW); TRebarInfo.fMask := RBBIM_SIZE or RBBIM_CHILD or RBBIM_CHILDSIZE or RBBIM_STYLE; TRebarInfo.cxMinChild := TRebarRect.Right - TRebarRect.Left; TRebarInfo.cyMinChild := TRebarRect.Bottom - TRebarRect.Top + 2; TRebarInfo.cx := 100; TRebarInfo.cxIdeal := cxIdeal; TRebarInfo.fStyle := RBBS_CHILDEDGE or RBBS_NOGRIPPER or RBBS_GRIPPERALWAYS or RBBS_BREAK; TRebarInfo.wID := ID_SYSREBAR_TOOLB; TRebarInfo.hwndChild := hChildWind; SendMessageW(hMenuRebar, RB_INSERTBAND, WPARAM(-1), LPARAM(@TRebarInfo)); end; end; end; | Само окно: Код: 101 DIALOGEX 0, 0, 200, 10 STYLE DS_FIXEDSYS | WS_POPUP | WS_VISIBLE CAPTION "" LANGUAGE LANG_RUSSIAN, 0x1 FONT 8, "MS Shell Dlg" { } | Когда тыкаем курсором на это окно в ребаре - заголовок программы становится неактивным - понятно что ткнули на другое окно. Но ведь почему оно не полностью дочернее на родителе? Даже если понаставить hMenuRebar вкачестве родителя у CreateDialog, ребар ведь дочерен по отношению окна программы, так почему ребар не выступает вкачестве родителя с загруженном диалогу? Может стили окна еще нужны дополнительные? И еще вопрос. Почему программа начинает потреблять много ЦП с таким кодом? Код: WM_PAINT: begin GetClientRect(GetDlgItem(hMainApp, ID_LISTVIEW_FILES), lpRect); iCount := SendMessageW(GetDlgItem(hMainApp, ID_LISTVIEW_FILES), LVM_GETITEMCOUNT, 0, 0); if iCount < 1 then begin ListDC := GetDC(GetDlgItem(hMainApp, ID_LISTVIEW_FILES)); SetTextColor(ListDC, GetSysColor(COLOR_WINDOWTEXT)); SetBkColor(ListDC, GetSysColor(COLOR_WINDOW)); SetBkMode(ListDC, TRANSPARENT); lpRect.Top := lpRect.Top + 25; DrawTextW(ListDC, PWideChar(WideString('test')), -1, lpRect, DT_CENTER or DT_WORDBREAK or DT_NOPREFIX or DT_NOCLIP); ReleaseDC(GetDlgItem(hMainApp, ID_LISTVIEW_FILES), ListDC); end; Result := 1; end; | Суть: есть листвью и если строк в нем нет - отображаем сообщение что он пустой. Может надо помудрить через BeginPaint? Просто если начать изменять размеры - надпись затирается и даже при перекрытии другим окном с последующим убиранием надпись пропадает с контрола. |