Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Delphi: Система, Windows API > Чисто WinAPI


Автор: DemonXpPro 04.01.09, 16:17
Добрый день.
Пишу программу на WinAPI.
Создал TabSheet с помощью:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    TabSheet := CreateWindow(WC_TABCONTROL, '', WS_CHILD or WS_VISIBLE, 2, 0, 320, 227, Handle, TabSheet, hInst, nil);
    SendMessage(TabSheet, WM_SETFONT, hFont, 0);
    SendMessage(TabSheet, TCM_SETIMAGELIST, 0, ImageList);
    TabItem.mask := TCIF_TEXT or TCIF_IMAGE;
    TabItem.pszText := 'Пароль';
    TabItem.cchTextMax := 0;
    TabItem.iImage := 0;
    SendMessage(TabSheet, TCM_INSERTITEM, 0, longint(@TabItem));
    TabItem.iImage := 1;
    TabItem.pszText := 'Горячие клавиши';
    SendMessage(TabSheet, TCM_INSERTITEM, 1, longint(@TabItem));

сделал две закладки.
Вопрос: Какие мне ловить сообщения чтобы узнать, что выбрана другая закладка.

И еще.
Создал Лабел, но цвет заливки на TabSheet отличается от заливки на Label, как поменять цвет заливки на Label?

Автор: ElcnU 04.01.09, 16:49
Цитата msdn
TCN_SELCHANGE Notification

---------------------------------------------------

Notifies a tab control's parent window that the currently selected tab has changed. This message is sent in the form of a WM_NOTIFY message.

Автор: ЫукпШ 04.01.09, 16:58
Цитата DemonXpPro @
Вопрос: Какие мне ловить сообщения чтобы узнать, что выбрана другая закладка.

И еще.
Создал Лабел, но цвет заливки на TabSheet отличается от заливки на Label, как поменять цвет заливки на Label?

Приблизительно так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
     switch (message)
     {
       case WM_NOTIFY:
     
       NMHDR *ptab = (LPNMHDR) lParam;
     
       if ((ptab->code == TCN_SELCHANGE) && (ptab->hwndFrom == hwnd))
       {
     // узнать номер нового таба
         tab_active = TabCtrl_GetCurSel ((HWND)ptab->hwndFrom);
     
       }
       break;
    ...
     }


2.) Не совсем понимаю, что такое Label. :(

Вероятно надо обрабатывать сообщение WM_CTLCOLORSTATIC.
Или одно из группы: WM_CTLCOLORxxx

Автор: B.V. 04.01.09, 17:08
Цитата DemonXpPro @
Создал Лабел, но цвет заливки на TabSheet отличается от заливки на Label, как поменять цвет заливки на Label?


Цвет заливки по умолчанию должен быть одинаков.
Можно зарисовать все градиентом из темы -- EnableThemeDialogTexture

Автор: DemonXpPro 04.01.09, 17:47
э. вот скрин. по поводу заливки

Добавлено
Да. и что за структура "LPNMHDR"

Автор: ElcnU 04.01.09, 17:53
сделай статик прозрачным.
как сказали в 3м посте лови WM_CTLCOLORSTATIC и возвращай кисть нужного цвета

чтоб статик был прозрачным должна возвращаться кисть полученная следующим образом:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    GetStockObject(NULL_BRUSH);


Добавлено
Цитата DemonXpPro @
Да. и что за структура "LPNMHDR"

это указатель на экземпляр структуры.... в мсдн ведь всё написано.... параметр сообщения

Автор: DemonXpPro 04.01.09, 18:06
Цитата ЫукпШ @
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
     switch (message)
     {
       case WM_NOTIFY:
     
       NMHDR *ptab = (LPNMHDR) lParam;
     
       if ((ptab->code == TCN_SELCHANGE) && (ptab->hwndFrom == hwnd))
       {
     // узнать номер нового таба
         tab_active = TabCtrl_GetCurSel ((HWND)ptab->hwndFrom);
     
       }
       break;
    ...
     }

Большое спасибо.

-Added
Цитата ElcnU @
сделай статик прозрачным.
как сказали в 3м посте лови WM_CTLCOLORSTATIC и возвращай кисть нужного цвета

чтоб статик был прозрачным должна возвращаться кисть полученная следующим образом:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    GetStockObject(NULL_BRUSH);

А нельзя ли поподробнее(в коде).
Просто я в вин апи нидавно, вот учусь :)
Я не понил куда возвращать?

Автор: ElcnU 04.01.09, 18:27
Цитата DemonXpPro @
А нельзя ли поподробнее(в коде).

на си
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    switch(message)
    {
    case WM_CTLCOLORSTATIC:
        if(GetDlgItem(IDC_MY_STATIC)==(HWND)lParam)
        {
            static HBRUSH hbrBackGnd=(HBRUSH)::GetStockObject(NULL_BRUSH);
            return hbrBackGnd;
        }
        break;
    ...


Цитата DemonXpPro @
Я не понил куда возвращать?

из оконной функции. смотри справку по указанному сообщению

Автор: DemonXpPro 04.01.09, 18:48
Цитата ElcnU @
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    switch(message)
    {
    case WM_CTLCOLORSTATIC:
        if(GetDlgItem(IDC_MY_STATIC)==(HWND)lParam)
        {
            static HBRUSH hbrBackGnd=(HBRUSH)::GetStockObject(NULL_BRUSH);
            return hbrBackGnd;
        }
        break;
    ...

Спасибо. Сработало!

Добавлено
Всем спасибо.

Автор: DemonXpPro 06.01.09, 17:47
Блин. чево то опять не получается. :(

Вот как я все делаю(пишу на делфах).
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    program WB;
     
    uses
      windows, messages, commctrl, XPMan; //Используемые модули
     
    {$R icons.res}
     
    var
      WinClass : TWndClass;
      hInst : HWND;
      Handle : HWND;
      Msg : TMSG;
      hFont : HWND;
      Label1, Label2, Label3, Label4, Label5, Label6: HWND;
      Edit1, Edit2, Edit3, Edit4 : HWND;
      cRunWithWindows : HWND;
      TabSheet: HWND;
      TabItem: TTCItem;
      ImageList: HWND;
      bNewChangePasswd, bExit : HWND;
     
    procedure ShutDown;
    begin
      DeleteObject(hFont);
      UnRegisterClass('MyFormClass', hInst);
      ExitProcess(hInst);
    end;
     
    function WindowProc(hwnd, msg, wparam, lparam: longint): longint; stdcall;
    var
    hbrBackGnd: HBRUSH;
    begin
      case Msg of
    WM_COMMAND:
    if (lParam = bExit) and (HiWord(wParam) = BN_CLICKED) then
      halt;
                
      WM_DESTROY: ShutDown;
      WM_ENDSESSION: if wParam = 1 then ShutDown;
      
      //////////////////////////////////////////////////////////////////////////////
      /// КАК  ПРАВИЛЬНО ОБРАБАТЫВАТЬ????? ИЛИ МОЖЕТ БЫТЬ НУЖНО ОБРАБАТЫВАТЬ WM_PAINT??????????
      //////////////////////////////////////////////////////////////////////////////
      WM_CTLCOLORSTATIC: if lParam <> cRunWithWindows then
        begin
        hbrBackGnd := GetStockObject(NULL_BRUSH);
        Result := hbrBackGnd;
        exit;
        end;  
      //////////////////////////////////////////////////////////////////////////////
      end;
      Result := DefWindowProc(hwnd, msg, wparam, lparam);
    end;
     
    begin
    hInst := GetModuleHandle(nil);
      with WinClass do
      begin
       Style := CS_PARENTDC;
       hIcon := LoadIcon(hInst, PChar('MAINICON'));
       lpfnWndProc := @WindowProc;
       hInstance := hInst;
       hbrBackground := COLOR_BTNFACE + 1;
       lpszClassName := 'MyFormClass';
       hCursor := LoadCursor(0, IDC_ARROW);
      end;
    InitCommonControls;
    RegisterClass(WinClass);
    // Создание главного окна программы
    Handle := CreateWindowEx(0, 'MyFormClass', 'Настройки программы', WS_VISIBLE or WS_SYSMENU, 320, 230, 330, 312, 0, 0, hInst, nil);
    // Создание шрифта
    hFont := CreateFont(-11, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE, 'MS Sans Serif');
    // Создание ImageList для TabSheet
    ImageList := ImageList_Create(16, 16, ILC_COLOR32 or ILC_MASK, 10, 10);
    ImageList_AddIcon(ImageList, LoadIcon(hInstance, 'Z0'));
    ImageList_AddIcon(ImageList, LoadIcon(hInstance, 'Z1'));
    // Создание TabSheet
    TabSheet := CreateWindow(WC_TABCONTROL, '', WS_CHILD or WS_VISIBLE, 2, 0, 320, 227, Handle, TabSheet, hInst, nil);
    SendMessage(TabSheet, WM_SETFONT, hFont, 0);
    SendMessage(TabSheet, TCM_SETIMAGELIST, 0, ImageList);
    // Создание вкладок на TabSheet
    TabItem.mask := TCIF_TEXT or TCIF_IMAGE;
    TabItem.pszText := 'Пароль';
    TabItem.cchTextMax := 0;
    TabItem.iImage := 0;
    SendMessage(TabSheet, TCM_INSERTITEM, 0, longint(@TabItem));
    TabItem.iImage := 1;
    TabItem.pszText := 'Горячие клавиши';
    SendMessage(TabSheet, TCM_INSERTITEM, 1, longint(@TabItem));
    // Создание надписи
    Label1 := CreateWindow('Static', 'Старый пароль:', WS_CHILD or SS_NOTIFY or SS_LEFT or WS_VISIBLE, 8, 24, 80, 13, Handle, 0, hInst, nil);
    SendMessage(Label1, WM_SETFONT, hFont, 0);
    // Создание надписи
    Label2 := CreateWindow('Static', 'Новый пароль:', WS_CHILD or SS_NOTIFY or SS_LEFT or WS_VISIBLE, 8, 64, 76, 13, Handle, 0, hInst, nil);
    SendMessage(Label2, WM_SETFONT, hFont, 0);
    // Создание надписи
    Label3 := CreateWindow('Static', 'Повторить новый пароль:', WS_CHILD or SS_NOTIFY or SS_LEFT or WS_VISIBLE, 8, 104, 131, 13, Handle, 0, hInst, nil);
    SendMessage(Label3, WM_SETFONT, hFont, 0);
    // Создание надписи
    Label4 := CreateWindow('Static', 'Подсказка к паролю:', WS_CHILD or SS_NOTIFY or SS_LEFT or WS_VISIBLE, 8, 160, 109, 13, Handle, 0, hInst, nil);
    SendMessage(Label4, WM_SETFONT, hFont, 0);
    // Создание надписи
    Label5 := CreateWindow('Static', 'Статус:', WS_CHILD or SS_NOTIFY or SS_LEFT or WS_VISIBLE, 8, 144, 37, 13, Handle, 0, hInst, nil);
    SendMessage(Label5, WM_SETFONT, hFont, 0);
    // Создание надписи
    Label6 := CreateWindow('Static', 'Label6', WS_CHILD or SS_NOTIFY or SS_LEFT or WS_VISIBLE, 160, 24, 154, 197, Handle, 0, hInst, nil);
    SendMessage(Label6, WM_SETFONT, hFont, 0);
    // Создание Edit'a
    Edit1 := CreateWindowEx(WS_EX_CLIENTEDGE, 'Edit', '', WS_CHILD or ES_AUTOHSCROLL or WS_VISIBLE, 8, 38, 145, 21, Handle, 0, hInst, nil);
    SendMessage(Edit1, WM_SETFONT, hFont, 0);
    // Создание Edit'a
    Edit2 := CreateWindowEx(WS_EX_CLIENTEDGE, 'Edit', '', WS_CHILD or ES_AUTOHSCROLL or WS_VISIBLE, 8, 80, 145, 21, Handle, 0, hInst, nil);
    SendMessage(Edit2, WM_SETFONT, hFont, 0);
    // Создание Edit'a
    Edit3 := CreateWindowEx(WS_EX_CLIENTEDGE, 'Edit', '', WS_CHILD or ES_AUTOHSCROLL or WS_VISIBLE, 8, 120, 145, 21, Handle, 0, hInst, nil);
    SendMessage(Edit3, WM_SETFONT, hFont, 0);
    // Создание Edit'a
    Edit4 := CreateWindowEx(WS_EX_CLIENTEDGE, 'Edit', '', WS_CHILD or ES_AUTOHSCROLL or WS_VISIBLE, 8, 176, 145, 21, Handle, 0, hInst, nil);
    SendMessage(Edit4, WM_SETFONT, hFont, 0);
    // Создание кнопки для создания/изменение пароля
    bNewChangePasswd := CreateWindow('Button', 'Создать/Изменить пароль', WS_CHILD or BS_TEXT or WS_VISIBLE, 8, 200, 145, 21, Handle, bNewChangePasswd, hInst, nil);
    SendMessage(bNewChangePasswd, WM_SETFONT, hFont, 0);
    // Создание checkbox'a для дообавления программы в автозапуск Windows
    cRunWithWindows := CreateWindow('Button', 'Запуск вместе с Windows', WS_CHILD or BS_AUTOCHECKBOX or WS_VISIBLE, 4, 230, 153, 17, Handle, 0, hInst, nil);
    SendMessage(cRunWithWindows, WM_SETFONT, hFont, 0);
    // Создание кнопки для закрытия окна
    bExit := CreateWindow('Button', 'Закрыть', WS_CHILD or BS_TEXT or WS_VISIBLE, 4, 252, 316, 21, Handle, bExit, hInst, nil);
    SendMessage(bExit, WM_SETFONT, hFont, 0);
     
     
     while(GetMessage(Msg, 0, 0, 0)) do
      begin
      TranslateMessage(Msg);
      DispatchMessage(Msg);
     end;
    end.


Помогите, почему заливки не совпадают на TabSheet и всех Static'ах?
Подключаю исходники, только помогите!

Автор: B.V. 06.01.09, 18:05
Е-мае... ты тоже не знаешь, что э.у. на вкладках по хорошему должны лежать на диалогах-страничках?

Автор: DemonXpPro 06.01.09, 18:10
Цитата B.V. @
Е-мае... ты тоже не знаешь, что э.у. на вкладках по хорошему должны лежать на диалогах-страничках?

Я немного не понял. Что ты имеешь в виду?
Поясни.

Автор: B.V. 06.01.09, 18:20
Сначала создавай диалог без рамки, затем создавай static'и и прочие э.у. на нем, и затем делай этот диалог дочерним окну-родителю TabControl'а. Для того, что бы вкладка была затекстурена в соответствии с темой (Аеро или ХР-темой), вызови в конце EnableThemeDialogTexture для диалога-странички.

Автор: DemonXpPro 06.01.09, 18:23
Цитата B.V. @
Сначала создавай диалог без рамки, затем создавай static'и и прочие э.у. на нем, и затем делай этот диалог дочерним окну-родителю TabControl'а. Для того, что бы вкладка была затекстурена в соответствии с темой (Аеро или ХР-темой), вызови в конце EnableThemeDialogTexture для диалога-странички.

Ну в общих чертах понятно.
Только вот хотелось бы это в коде увидеть...

Добавлено
Да. и где находится EnableThemeDialogTexture?

Автор: B.V. 06.01.09, 18:30
Цитата DemonXpPro @
Только вот хотелось бы это в коде увидеть...


Ну, вот тебе в коде: http://code.google.com/p/easybar/source/browse/trunk/FilePropDlg.cpp

Цитата DemonXpPro @
Да. и где находится EnableThemeDialogTexture?


В Дельфи? Понятия не имею.

Добавлено
Заглянул в Дельфи, оказывается, у них есть подраздел Дельфи WinAPI. А в подразделе твой дубль Чито WinAPI
Нехорошо получается

Автор: B.V. 06.01.09, 18:36
M
Тема перенесена из WinAPI

Автор: DemonXpPro 06.01.09, 18:39
Цитата B.V. @
Добавлено
Заглянул в Дельфи, оказывается, у них есть подраздел Дельфи WinAPI. А в подразделе твой дубль Чито WinAPI
Нехорошо получается

Да. я знаю. просто там ступил один раз и туда и сюда тему сделал.
Больше так не буду . :)

-Added
Цитата B.V. @
Ну, вот тебе в коде: http://code.google.com/p/easybar/source/browse/trunk/FilePropDlg.cpp

Так ведь тута, имеется ввиду, что окно создается из ресурсов?
А я ни так делаю.
Так я и ничего ни понил. :(

Автор: B.V. 06.01.09, 18:42
Цитата DemonXpPro @
Так ведь тута, имеется ввиду, что окно создается из ресурсов?


Ну, замени создание окна из шаблона диалога в ресурсах на CreateWindow

Автор: DemonXpPro 06.01.09, 18:44
Я просто не понимаю самой идеи?
В чем смысл????
Не доходит до меня ид***та? :)
Можно рассписать это в подробностях исходя из привиденного мною кода моей программы?

Автор: ElcnU 06.01.09, 20:40
Цитата DemonXpPro @
Я просто не понимаю самой идеи?

идея самая обыкновенная:
1) контролам типа кнопочек, эдитов итд предписано лежать на диалогах.
Цитата msdn
A dialog box is a temporary window an application creates to retrieve user input. An application typically uses dialog boxes to prompt the user for additional information for menu items. A dialog box usually contains one or more controls (child windows) with which the user enters text, chooses options, or directs the action.

остальные варианты, ИМХО, от лукавого....
2)как сказал B.V., вкладка должна быть одним окном, которое несет на себе дочерние контролы
3) читам мсдн раздел Creating a Tabbed Dialog Box

могу привести еще пример 23й пост

ЗЫ:что тебе мешает создать диалог в ресурсах?

Автор: DemonXpPro 06.01.09, 20:46
Цитата ElcnU @
что тебе мешает создать диалог в ресурсах?

Ничего.
Разве без вшития в ресурсы ни как?
Я бы хотел без ресурсов.
да и можно где нить пример на delphi?

Автор: ElcnU 06.01.09, 21:01
Цитата DemonXpPro @
Разве без вшития в ресурсы ни как?

да не читай ты через пост!!!! в 18м посту подсказка была. остальное решать тебе...

Цитата DemonXpPro @
да и можно где нить пример на delphi?

а че тебя так язык пугает? всё равно winapi ;)

Автор: DemonXpPro 06.01.09, 21:22
Цитата ElcnU @
а че тебя так язык пугает?

сам не знаю. просто не понятно.

Автор: Dem_max 07.01.09, 14:54
а зачем в Delphi WinApi ??????????? чем тебя VCL не устраивает?

Автор: DemonXpPro 07.01.09, 14:57
Цитата Dem_max @
а зачем в Delphi WinApi ??????????? чем тебя VCL не устраивает?

Размеры большие получаются.
Написал программу на VCL, а теперь хочу переписать на WinAPI

Автор: Maksim V. 08.01.09, 10:10
Хм, когда-то делал такое. Вот исходник. Выцепи что необходимо.

Автор: ALXR 09.01.09, 15:55
С таким подходом к созданию приложения получишь один серьезный недостаток: не будет работать переход между контролами по нажатию Tab. Дабы избежать этого, рекомендуется воспользоваться диалогами из ресурсов с CreateDialogParam или CreateDialogIndirectParam с созданием шаблонов диалогов вручную. Думаю, в делфи что-то такое должно быть предусмотрено...

Автор: navodri 03.06.18, 08:10
В библиотеке Win32API Library есть пример TabControl.

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