Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++: WinAPI
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
PinkPink
9 / 9 / 5
Регистрация: 10.05.2012
Сообщений: 289
1

Как создать 2 скроллбара, и различить их при получении события?

01.11.2012, 19:57. Просмотров 2009. Ответов 15
Метки нет (Все метки)

Как создать 2 горизонтальных скроллбара? И как потом получать события и различать от какого из скроллбаров пришло событие?
Написала вот что:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
static TCHAR szClass[] = _T("win32app");
static TCHAR szTitle[] = _T("Работа с цветом");
static TCHAR ca[] = _T("scrollbar");
static TCHAR cb[] = _T("static");
static TCHAR cc[] = _T("scrollbar");
static TCHAR cd[] = _T("static");
#define CM_GET_COLOR         1003
#define CM_FILE_QUIT    1001
 
HINSTANCE hInst;
static HWND hEdit;
BOOL RC(WNDPROC, LPCTSTR, UINT);
int a=0;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//функция оконной процедуры
 
BOOL RC(WNDPROC WndProc, LPCTSTR Name, UINT brBackground)
{
WNDCLASS wc = { 0 }; 
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wc.lpfnWndProc=WndProc; //указывает на функцию окна
    wc.hInstance=hInst; //указывает на дескриптор текущего приложения
    wc.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_APPLICATION)); //иконка
    wc.hCursor=LoadCursor(NULL, IDC_ARROW); //курсор
    wc.hbrBackground=(HBRUSH)( brBackground +1); //  задает дескриптор кисти закрашивания фона окна
    wc.lpszMenuName=NULL; // имя 
    wc.lpszClassName=Name; //имя класса окон
return (RegisterClass(&wc)!=0);
}
 
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)  ///главная функция
{
    hInst=hInstance;
    if(!RC(WndProc,szClass,COLOR_WINDOW)) return FALSE;
       //создаём окно
 
HWND hwnd = CreateWindow(
    szClass,
    szTitle,
    WS_OVERLAPPEDWINDOW|WS_VISIBLE,
    CW_USEDEFAULT, CW_USEDEFAULT,
    500, 500,
    NULL,
    (HMENU)NULL,
    hInstance,
    NULL
);
if (!hwnd)
{
    MessageBox(NULL,
        _T("Call to CreateWindow failed!"),
        _T("Win32 Guided Tour"),
        NULL);
 
    return FALSE;
}
 
//отображаем окно
 
ShowWindow(hwnd,
    nCmdShow);
UpdateWindow(hwnd);
 
//цикл обработки сообщений отправляемых ОС
 
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
 
    return (int) msg.wParam;
 
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)//добавляем функциональные возможности
{
    PAINTSTRUCT ps;
    HDC hDC;
    SIZE size;
    char *str ="Пробный вывод";
    HFONT hNFont, hOFont;
 
    TCHAR greeting[] = _T("");
    static HWND hxScroll,hyScroll;
    static int nxPos,nxMin,nxMax,nyPos,nyMin,nyMax;
    switch (message)
    {
 
        case WM_PAINT:
        static LOGFONT lf;
        hDC = BeginPaint(hwnd, &ps);
        SetBkMode(hDC, TRANSPARENT);
        lf.lfCharSet=DEFAULT_CHARSET;
        lf.lfPitchAndFamily=DEFAULT_PITCH;
        lf.lfHeight=20;
        lf.lfWeight=FW_BOLD;
        GetTextExtentPoint32A(hDC, str, strlen(str), &size);
 
 
                hNFont=CreateFontIndirect(&lf);
                hOFont=(HFONT)SelectObject(hDC,hNFont);
                SetTextColor(hDC, RGB(0,0,0));
                TextOutA(hDC, 250, 50, str, size.cx);
 
        SelectObject(hDC,hOFont);
        DeleteObject(hNFont);
        EndPaint(hwnd, &ps);
        break;
 
        case WM_CREATE:
            hxScroll=CreateWindow(ca,NULL,WS_CHILD|WS_VISIBLE|SBS_HORZ,20,60,200,25,hwnd,(HMENU)-1,hInst,NULL);
            nxPos=100;nxMin=1;nxMax=200;
            SetScrollRange(hxScroll,SB_CTL,nxMin,nxMax,TRUE);
            SetScrollPos(hxScroll,SB_CTL,nxPos,TRUE);
 
            hyScroll=CreateWindow(cd,NULL,WS_CHILD|WS_VISIBLE|SBS_HORZ,20,120,200,25,hwnd,(HMENU)-1,hInst,NULL);
            nyPos=200;nyMin=1;nyMax=200;
            SetScrollRange(hyScroll,SB_CTL,nyMin,nyMax,TRUE);
            SetScrollPos(hyScroll,SB_CTL,nyPos,TRUE);
            return 0;
        break;
 
        case WM_HSCROLL:
            {
                switch(LOWORD(wParam))
                {
                case SB_PAGERIGHT:
                    {nxPos+=10;break;}
                case SB_LINERIGHT:
                    {nxPos+=1;break;}
                case SB_PAGELEFT:
                    {nxPos-=10;break;}
                case SB_LINELEFT:
                    {nxPos-=1;break;}
                case SB_TOP:
                    {nxPos=nxMin;break;}
                case SB_BOTTOM:
                    {nxPos=nxMax;break;}
                case SB_THUMBPOSITION:
                case SB_THUMBTRACK:
                    {nxPos=HIWORD(wParam);break;}
                default:break;
                }
                if(nxPos>nxMax)nxPos=nxMax;
                if(nxPos<nxMin)nxPos=nxMin;
                SetScrollPos(hxScroll,SB_CTL,nxPos,TRUE);
                if(nxPos==nxMax) EnableScrollBar(hxScroll,SB_CTL,ESB_DISABLE_RIGHT);
                return 0;
            }
        
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            }
        default:return DefWindowProc(hwnd, message, wParam, lParam);break;
    }
return 0;
}
В итоге один скроллбар выводится в нормальном виде, другой просто как серая полоса
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.11.2012, 19:57
Ответы с готовыми решениями:

Как различить события OnDblClick от OnClick
Проблема в том, что обработчик от события OnClick реагирует так же на событие...

События Скроллбара на StringGrid
Итак, к-во строк превысило высоту и появляется ... ScrollBar! Подскажите, плз...

Различить события сгенерированные пользователем и программой
К примеру у меня несколько разных контролов чекбоксы листбоксы и тд. Они...

Зацикливание при получении получении сообщения от клиента
Доброго времени суток! Уже выбился из сил... Суть моей проблемы в следующем....

Как создать обработчик события при нажатии на кнопки Развернуть во весь экран - Восстановить?
Народ, Хелп! Как написать или создать в Delphi событие при нажатии на эту пару...

15
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26490 / 17791 / 7037
Регистрация: 22.10.2011
Сообщений: 31,308
Записей в блоге: 6
01.11.2012, 20:46 2
Лучший ответ Сообщение было отмечено volvo как решение

Решение

Цитата Сообщение от PinkPink Посмотреть сообщение
один скроллбар выводится в нормальном виде, другой просто как серая полоса
Пардон, у тебя создается один скроллбар и один статик, а не 2 скроллбара...
0
PinkPink
9 / 9 / 5
Регистрация: 10.05.2012
Сообщений: 289
01.11.2012, 21:43  [ТС] 3
Цитата Сообщение от UI Посмотреть сообщение
Пардон, у тебя создается один скроллбар и один статик, а не 2 скроллбара...
вот где я накосячила!
спасибо!
а как мне теперь сделать чтобы они работали независимо? а то если я тащу один ползунок то и второй за ним таскается, как различать сообщения от того и от другого?
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26490 / 17791 / 7037
Регистрация: 22.10.2011
Сообщений: 31,308
Записей в блоге: 6
01.11.2012, 21:51 4
Проверяй, от какого из ScrollBar-ов пришло сообщение, и обрабатывай их по отдельности. Ты же обрабатываешь вместе, неважно, от какого из контролов пришло WM_HSCROLL, nxPos всё равно изменится. Как-то так:
C++
1
2
3
4
5
6
7
case WM_HSCROLL:
{
    if((HWND)lParam == hxScroll)
    {
        // первый скроллбар, обрабатываем
    }
}
, аналогично - со вторым.
1
PinkPink
9 / 9 / 5
Регистрация: 10.05.2012
Сообщений: 289
02.11.2012, 00:01  [ТС] 5
Мне нужно изменять цвет текста при передвижении ползунка. Возможно ли перерисовать текст и изменить цвет при обработке события? или цвет задаётся только в PAINT? пытаюсь сделать вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
case SB_PAGERIGHT:
            {
                nxPos+=10;
                hNFont=CreateFontIndirect(&lf);
                hOFont=(HFONT)SelectObject(hDC,hNFont);
                SetTextColor(hDC, RGB(15,40,85));
                TextOutA(hDC, 120, 200, str, size.cx);
                SelectObject(hDC,hOFont);
                UpdateWindow(hwnd);
                break;
                        }
и никаких изменений
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26490 / 17791 / 7037
Регистрация: 22.10.2011
Сообщений: 31,308
Записей в блоге: 6
02.11.2012, 00:50 6
PinkPink, а почему нельзя по WM_PAINT создавать цвет не RGB(0, 0, 0), а уже исходя из значений nxPos, скажем,
C++
1
2
3
                hOFont=(HFONT)SelectObject(hDC,hNFont);
                SetTextColor(hDC, RGB(0,0,nxPos)); // Вот так
                TextOutA(hDC, 250, 50, str, size.cx);
, а при изменении позиции скроллбара просто InvalidateRect-ом вызвать перерисовку окна или его части, тогда цвет текста будет соответствовать выбранному при помощи скроллбара...

По поводу, почему у тебя не работает - а что у тебя в hDC, можно уточнить?
0
PinkPink
9 / 9 / 5
Регистрация: 10.05.2012
Сообщений: 289
02.11.2012, 01:57  [ТС] 7
Цитата Сообщение от UI Посмотреть сообщение
PinkPink, а почему нельзя по WM_PAINT создавать цвет не RGB(0, 0, 0), а уже исходя из значений nxPos, скажем,
C++
1
2
3
                hOFont=(HFONT)SelectObject(hDC,hNFont);
                SetTextColor(hDC, RGB(0,0,nxPos)); // Вот так
                TextOutA(hDC, 250, 50, str, size.cx);
, а при изменении позиции скроллбара просто InvalidateRect-ом вызвать перерисовку окна или его части, тогда цвет текста будет соответствовать выбранному при помощи скроллбара...

По поводу, почему у тебя не работает - а что у тебя в hDC, можно уточнить?
спасибо, так и сделала
0
Den123
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 5
14.03.2013, 19:17 8
Блин, я создаю 2 скроллбара через окошко стандартное для создания формы, как понять от какого скроллбара приходит сообщение =(, в упор блин не пойму скроллбары #deifne IDC_SCROLLBAR1 и такой же ток с 2-кой хелп =((
0
PinkPink
9 / 9 / 5
Регистрация: 10.05.2012
Сообщений: 289
14.03.2013, 19:49  [ТС] 9
Цитата Сообщение от Den123 Посмотреть сообщение
Блин, я создаю 2 скроллбара через окошко стандартное для создания формы, как понять от какого скроллбара приходит сообщение =(, в упор блин не пойму скроллбары #deifne IDC_SCROLLBAR1 и такой же ток с 2-кой хелп =((
Я вот так различала:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 case WM_HSCROLL:
                        {
                                if((HWND)lParam == hxScroll)
                        {
                                        switch(LOWORD(wParam))
                                        {
                                        case SB_PAGERIGHT:
                                                {nxPos+=10;break;}
                                        ...
                                        default:break;
                                        }
                                    }
                                else if((HWND)lParam == hyScroll)
                                        {
                                                switch(LOWORD(wParam))
                                        {
                                            ...
                                        }
                                }
                                else 
                                {
                                    
                                    switch(LOWORD(wParam))
                                    {
                                    ...
                                    }
                                }
                                return 0;
                        }
У меня их было 3 hxScroll, hyScroll, hzScroll
Объявлены вот так:
static HWND hxScroll,hyScroll,hzScroll;
0
Den123
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 5
14.03.2013, 23:28 10
if((HWND)lParam == IDC_SCROLLBAR1) несоответствие типов..., я так сразу и пробовал =(, вообще С не перевариваю, я к делфи привык а тут блин надо че-то придумать =((, ну или забить и переписать все в делфи...
0
PinkPink
9 / 9 / 5
Регистрация: 10.05.2012
Сообщений: 289
14.03.2013, 23:31  [ТС] 11
Цитата Сообщение от Den123 Посмотреть сообщение
if((HWND)lParam == IDC_SCROLLBAR1) несоответствие типов..., я так сразу и пробовал =(, вообще С не перевариваю, я к делфи привык а тут блин надо че-то придумать =((, ну или забить и переписать все в делфи...
хмм, а код можно посмотреть?
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26490 / 17791 / 7037
Регистрация: 22.10.2011
Сообщений: 31,308
Записей в блоге: 6
15.03.2013, 01:20 12
Цитата Сообщение от Den123 Посмотреть сообщение
я так сразу и пробовал
Это не то, что тебе советовали, кстати. Советовали сравнивать lParam с хендлом, а не с идентификатором. Потому что
lParam
If the message is sent by a scroll bar control, this parameter is the handle to the scroll bar control
0
Den123
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 5
15.03.2013, 09:19 13
Да я блин понимаю, у тебя они как static HWND Объявлены и ты можешь сравнивать а у меня они в окне нарисованы и дополнительно никак не объявлены ток #define, я так понимаю их стандартная прилага описывать должна, то что ты вручную пишешь, и у неё должны быть возвращаемые параметры, так вот как мне добраться до этих параметров?! чтобы можно было опросить какой все-таки скроллбар был задействован.

Добавлено через 7 минут
да что код, там вагон строк по сути из нужного :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define IDC_SCROLLBAR1         1052
#define IDC_SCROLLBAR2         1053
....
case WM_HSCROLL:
            {
                switch(LOWORD(wParam))
                {
                  case SB_LINERIGHT:
                    {}
                case SB_LINELEFT:
                    {nxPos-=1;break;}
                case SB_THUMBPOSITION:
                case SB_THUMBTRACK:
                    {nxPos=HIWORD(wParam);break;}
                default:break;
                }
                      return 0;
            }
я скроллбаром вообще как спином пользуюсь, т.к. при использовании спина диалоговое окно не запускается, хотя в диспетчере задач в процессах прога отображается...
вот это я руками не прописываю
C++
1
2
3
4
 hxScroll=CreateWindow(ca,NULL,WS_CHILD|WS_VISIBLE|SBS_HORZ,20,60,200,25,hwnd,(HMENU)-1,hInst,NULL);
            nxPos=100;nxMin=1;nxMax=200;
            SetScrollRange(hxScroll,SB_CTL,nxMin,nxMax,TRUE);
            SetScrollPos(hxScroll,SB_CTL,nxPos,TRUE);
я так понимаю при создании формы через стандартное окно с панелькой(как в билдере) это прописывает за меня прилага какая-то поэтому как мне получить эквивалент hxScroll для сравнения, или я просто хз как работает сишка.

Добавлено через 1 минуту
Цитата Сообщение от UI Посмотреть сообщение
Это не то, что тебе советовали, кстати. Советовали сравнивать lParam с хендлом, а не с идентификатором. Потому что
как мне до хендла добраться?!
0
Den123
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 5
16.03.2013, 17:59 14
Так, я понял принцип работы судя по всему то как я их создал делает невозможным их различать поскольку они будут иметь один и тот же хендл материнского окна, тогда другой вопрос как мне получить информацию от спина, а именно увеличилось его значение или нет, есть ли такая функция ну или опросить текущее значение, я бы сравнивал с предыдущим?! =)
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26490 / 17791 / 7037
Регистрация: 22.10.2011
Сообщений: 31,308
Записей в блоге: 6
17.03.2013, 18:04 15
Цитата Сообщение от Den123 Посмотреть сообщение
это прописывает за меня прилага какая-то
Может, тогда лучше было обратиться в соответствующий форум? Потому что в WinAPI нет "каких-то прилаг", которые это сделают за тебя, а разные надстройки не тут обсуждаются...

Цитата Сообщение от Den123 Посмотреть сообщение
как мне до хендла добраться?!
GetDlgItem(hwnd, IDC_SCROLLBAR1) вернет тебе хендл первого скроллбара, если что, его можно сравнивать с (HWND)lParam... (если скролл создавался твоей "прилагой" правильно, то есть, если этот самый IDC_SCROLLBAR1 передавался 9-ым параметром в CreateWindow. Ты сам руками не делаешь, кто-то же делает, правда, не просто ж так тебе даны ID контролов?)

Со вторым скроллбаром - аналогично.
1
Den123
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 5
18.03.2013, 23:21 16
Спасибо, добрался до хендлов, дальше все было весьма просто =)
0
18.03.2013, 23:21
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.03.2013, 23:21

Как различить нажатие одноимённых курсорных клавиш (при выключенном NumLock)?
1. В правой части клавиатуры - 2 группы курсорных клавиш: одна - переключается...

1c 8.2 Как при получении и записи объекта
Как при получении и записи объекта (справочника) программно , процедура...

Как разбудить компьютер при получении e-mail?
Здравствуйте. Нужно автоматически будить комп при получении почты и чтобы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru