Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
41 / 13 / 4
Регистрация: 22.07.2013
Сообщений: 145
1

Получить текст из Edit1 и переслать в Edit2

16.06.2016, 21:36. Показов 1757. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Приветствую знатоков С++. Возник вопрос по WinApi, подскажите кто знает. В родительском окне есть 2 текстовых поля :
C++ (Qt)
1
2
3
4
5
CreateWindow(TEXT("edit"), TEXT(" Текст сначала "), 
WS_VISIBLE | WS_CHILD | ES_UPPERCASE, 
30, 40, 300, 50, 
hWnd, (HMENU) IDB_Button1, NULL, NULL 
);
и
C++ (Qt)
1
2
3
4
5
CreateWindow(TEXT("edit"), TEXT(" Текст потом"), 
WS_VISIBLE | WS_CHILD | ES_UPPERCASE, 
30, 400, 300, 50, 
hWnd, (HMENU) IDB_Button2, NULL, NULL 
);
Нужно по щелчку мыши переслать введенный текст из IDB_Button1 в EDIT IDB_Button2. Казалось что ничего сложного нет. На кнопку вешаю команду :

C++ (Qt)
1
2
3
4
5
6
case WM_COMMAND: 
if (wParam == IDB_Button100) { 
WCHAR buf[1024]; 
GetDlgItemText (hWnd, IDB_Button1, buf, 1024); 
PostMessage(hWnd,IDB_Button2,0,(LPARAM)&buf); 
}
Однако несмотря на то, что при компиляции Visual Studio ошибок не выдает при щелчке на кнопку приложение закрывается. Если удалить PostMessage не закрывается. Думаю что ошибка в этой строчке. Подскажите пожалуйста как исправить? Реально перерыл пол интернета но решения так и не нашел. Заранее Спасибо.

Добавлено через 1 час 3 минуты
Кажется разобрался. Что бы просто переслать текст нужно использовать SetDlgItemText вместо Postmessege :

C++ (Qt)
1
2
GetDlgItemText (hWnd, IDB_Button1, buf, 1024); 
SetDlgItemText(hWnd, IDB_Button2, buf);
А как можно придать пересылаемому тексту стиль, например выровнять по правому краю ES_RIGHT ?

Добавлено через 4 часа 25 минут
Неужели никто не знает как при нажатии на кнопку приписать ES_LEFT полю EDIT ? Помогите пожалуйста.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.06.2016, 21:36
Ответы с готовыми решениями:

Если занят Edit1, то текст запишется в Edit2
При нажатии BitBtn в Edit1 записывается текст (например Edit1.Text:='abc'). Как сделать, чтобы,...

Как сохранить данные из Edit1 в Edit2, чтобы после перезагрузки программы сохраненное в Edit2 не удалялось?
Мир всем и привет ! Как сохранить данные из Edit1 в Edit2, чтобы после перезагрузки программы...

При нажатии на клавиши, добавлять через точку с запятой текст из Edit1 и Edit2 в ListBox
Здравствуйте. Мне нужно при нажатии на клавиши, добавлять текст из edit1 и edit 2 через точку с...

Создать программу которая при нажатии Button отсылает текст полей Edit1 и Edit2 на мыло
Создать программу которая при нажатии Button отсылает текст полей Edit1 и Edit2 на мыло

14
903 / 424 / 159
Регистрация: 02.04.2014
Сообщений: 1,206
17.06.2016, 10:27 2
Попробуй для Edit'а вызвать SetWindowLong с параметром GWL_EXSTYLE и соответствующей битовой маской.
1
41 / 13 / 4
Регистрация: 22.07.2013
Сообщений: 145
17.06.2016, 14:15  [ТС] 3
Не совсем понимаю как вызвать SetWindowLong именно для нужного EDITa а не того откуда текст копируется.
В функции SetWindowLong только 3 параметра hWnd (как я понял это дескриптор родительского окна на котором находятся Edit'ы ), nIndex и dwNewLong. nIndex = GWL_STYLE устанавливает новый стиль а dwNewLong = ES_LEFT (например) тогда?
Пробовал:
C++ (Qt)
1
SetWindowLong (hWnd,GWL_STYLE, ES_LEFT );
Но после нажатия меняется именно родительское окно а не поле Edit.
0
903 / 424 / 159
Регистрация: 02.04.2014
Сообщений: 1,206
17.06.2016, 19:52 4
Почему дескриптор родительского? В MSDN'e же английским по белому написано:
A handle to the window and, indirectly, the class to which the window belongs
И с третьим параметром неправильно. Перед установкой нового значения нужно сначала запросить старое, потом добавить к нему бит ES_LEFT и тогда уже записывать что получится. А иначе все бывшие биты стиля обнулятся.
Т.е. что то типа этого:
C++
1
2
3
LONG lOldValue = GetWindowLong(hEditControl, GWL_STYLE);
lOldValue |= ES_LEFT;
SetWindowLong(hEditControl, GWL_STYLE, lOldValue);
а почему нельзя сразу указать нужный стиль при создании окна?
1
41 / 13 / 4
Регистрация: 22.07.2013
Сообщений: 145
17.06.2016, 22:10  [ТС] 5
hEditControl - это дескриптор окна или Editа?
C++ (Qt)
1
LONG lOldValue = GetWindowLong(hEditControl, GWL_STYLE);
Извиняюсь, наверное туплю. winapi изучаю недавно. Перерыл кучу страниц но так и не смог полностью разобраться с дескрипторами. Д - это уникальный идентификатор любого объекта ? т.е. того же поля Edit(или например кнопки) или именно окна windows (родительского или дочернего) а не того что в этом окне ?

Добавлено через 3 минуты
Сразу стиль установить можно, но текст должен по команде свой стиль изменять: ES_CENTER при нажатии на кнопку 1, ES_RIGHT - при нажатии на кнопку 2 и т.д.

Добавлено через 34 минуты
Такой вариант тоже не срабатывает. Ссылка на неразрешенный внешний символ.
C++ (Qt)
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
LRESULT CALLBACK WndProc(HWND hWnd,   HWND Edit1, HWND Edit2,     UINT uMsg, WPARAM wParam, LPARAM lParam)
{
case WM_PAINT: 
            hDC = BeginPaint(hWnd, & ps); 
            GetClientRect(hWnd, & rect); 
            SetTextColor(hDC, colorText); 
            DrawText(hDC, mainMessage, -1, & rect, DT_WORDBREAK | DT_LEFT | DT_TOP); 
            EndPaint(hWnd, & ps); 
            break;
       case WM_DESTROY: 
            PostQuitMessage(NULL);
            break;
 
 case WM_CREATE:
                CreateWindow(TEXT("edit"), TEXT(" Введите текст "),
                WS_VISIBLE | WS_CHILD,
                30, 40, 300, 50,
                Edit1, (HMENU) EDIT1, NULL, NULL
            );
 
                CreateWindow(TEXT("edit"), TEXT(" Туть он будет потом "),
                WS_VISIBLE | WS_CHILD,
                30, 400, 300, 50,
                Edit2,(HMENU) EDIT2, NULL, NULL
            );
        CreateWindow(TEXT("button"), TEXT("ES_LEFT"),
                WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON,
                100, 120, 200, 20,
                hWnd, (HMENU)ES_LEFT1, NULL, NULL
            );
 
                case WM_COMMAND:
        if (wParam == ES_RIGHT1) {
 
            WCHAR buf[1024];        
                GetDlgItemText (hWnd, EDIT1, buf, 1024);
                SetDlgItemText(hWnd, EDIT2, buf);
 
                LONG lOldValue = GetWindowLong(Edit1, GWL_STYLE);
                lOldValue |= ES_LEFT;
                SetWindowLong(Edit2, GWL_STYLE, lOldValue); 
                        }   
}
0
903 / 424 / 159
Регистрация: 02.04.2014
Сообщений: 1,206
18.06.2016, 11:08 6
Да, дескриптор уникальный идентификатор. Вернее HANDLE. Они есть у всех объектов операционной системы: файлов, объектов синхронизации, окон, GDI, и т.п. Поля Edit, кнопки и любые другие контролы - это тоже окна как и содержащее их родительское окно, поэтому оконные handle'ы (т.е. HWND) у них у каждого свой.
Косяки последнего кода:
1) Слишком много параметров в WndProc. Их должно быть 4: WindowProc callback function. Откуда HWND Edit1, HWND Edit2 ?
2) В 33 строке кто присылает ES_RIGHT1 ? Кнопка то у тебя создается с идентификатором ES_LEFT1. (т.е. в этот блок ты вероятно никогда не попадешь)
1
41 / 13 / 4
Регистрация: 22.07.2013
Сообщений: 145
18.06.2016, 15:00  [ТС] 7
Если из WndProc убрать параметры Edit1 и Edit2 то они будут не определены для:

C++ (Qt)
1
2
3
4
5
CreateWindow(TEXT("edit"), TEXT(" Туть он будет потом "),
                WS_VISIBLE | WS_CHILD,
                30, 400, 300, 50,
                Edit2,(HMENU) EDIT2, NULL, NULL
            );
Пробую так:
C++ (Qt)
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
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HDC hDC; 
    PAINTSTRUCT ps; 
    RECT rect; 
    COLORREF colorText = RGB(0, 0, 0); 
 
    switch (uMsg) {
        case WM_PAINT: 
            hDC = BeginPaint(hWnd, & ps); 
            GetClientRect(hWnd, & rect); 
            SetTextColor(hDC, colorText);
            DrawText(hDC, mainMessage, -1, & rect, DT_WORDBREAK | DT_LEFT | DT_TOP); 
            EndPaint(hWnd, & ps); 
            break;
       case WM_DESTROY: 
            PostQuitMessage(NULL); 
            break;
 
        case WM_CREATE:
            
 
            CreateWindow(TEXT("edit"), TEXT(" Введите текст "),
                WS_VISIBLE | WS_CHILD,
                30, 40, 300, 50,
                Edit1, (HMENU) EDIT1, NULL, NULL
            );
            
            CreateWindow(TEXT("edit"), TEXT(" Туть он будет потом "),
                WS_VISIBLE | WS_CHILD,
                30, 400, 300, 50,
                Edit2,(HMENU) EDIT2, NULL, NULL
            );
            
            
            
            
            CreateWindow(TEXT("button"), TEXT("ES_LEFT"),
                WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON,
                100, 120, 200, 20,
                hWnd, (HMENU)ES_LEFT1, NULL, NULL
            );
 
                        
 
 
        case WM_COMMAND:
        if (wParam == ES_LEFT1) {
 
            WCHAR buf[1024];        
                GetDlgItemText (hWnd, EDIT1, buf, 1024);
                SetDlgItemText(hWnd, EDIT2, buf);
 
                LONG lOldValue = GetWindowLong(Edit2, GWL_STYLE);
                lOldValue = ES_LEFT;
                SetWindowLong(Edit2, GWL_STYLE, lOldValue); 
                        }
                            
 
 
 
        default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam); 
    }
Ошибки - не объявленные идентификаторы Edit1 и Edit2.
0
903 / 424 / 159
Регистрация: 02.04.2014
Сообщений: 1,206
18.06.2016, 18:21 8
Такой вопрос: почему для создания кнопки при вызове CreateWindow ты в качестве хэндла родительского окна указываешь hWnd, а для создания полей ввода (т.е. Edit'ов) пытаешься впихнуть какие-то неопознанные идентификаторы Edit1 и Edit2 ? Передавай hWnd, это же оно для них будет родительским окном.
1
41 / 13 / 4
Регистрация: 22.07.2013
Сообщений: 145
18.06.2016, 19:25  [ТС] 9
Ну, потому что если тут просто ставить hWnd то стиль будет изменен для всего родительского окна а не для конкретного поля
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
 case WM_COMMAND:
        if (wParam == ES_LEFT1) {
 
            WCHAR buf[1024];        
                GetDlgItemText (hWnd, EDIT1, buf, 1024);
                SetDlgItemText(hWnd, EDIT2, buf);
 
                LONG lOldValue = GetWindowLong(hWnd, GWL_STYLE);
                lOldValue = ES_LEFT;
                SetWindowLong(hWnd, GWL_STYLE, lOldValue); 
                        }
Как мне к SetWindowLong(hWnd, GWL_STYLE, lOldValue); прописать идентификатор именно Edit2?

Добавлено через 13 минут
При этом реагируют все кнопки а не только ES_LEFT1.

Добавлено через 12 секунд
При этом реагируют все кнопки а не только ES_LEFT1.
0
903 / 424 / 159
Регистрация: 02.04.2014
Сообщений: 1,206
18.06.2016, 20:45 10
Для получения хэндла поля ввода можно воспользоваться функцией GetDlgItem. А потом ему уже устанавливай стиль:
C++
1
2
3
HWND hEditChild = GetDlgItem(hWnd, EDIT2);
...
SetWindowLong(hEditChild , GWL_STYLE, ...);
Какие "все" кнопки если в WM_CREATE ты создаешь только одну? Кстати там еще "break" не хватает.

Наверное проще будет сделать Build->Clean..., заархивировать и прикрепить к сообщению весь проект.
1
41 / 13 / 4
Регистрация: 22.07.2013
Сообщений: 145
19.06.2016, 00:43  [ТС] 11
Все, их не много, это кнопки для разных стилей ES_CENTER, ES_LEFT, ES_RIGHT и т.д.
C++ (Qt)
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
  
case WM_CREATE:
           
 
            CreateWindow(TEXT("edit"), TEXT(" Введите текст "),
                WS_VISIBLE | WS_CHILD,
                30, 40, 300, 50,
                hWnd, (HMENU) EDIT1, NULL, NULL
            );
            
            CreateWindow(TEXT("edit"), TEXT(" Туть он будет потом "),
                WS_VISIBLE | WS_CHILD,
                30, 400, 300, 50,
                hWnd,(HMENU) EDIT2, NULL, NULL
            );
            
            
            
            
            CreateWindow(TEXT("button"), TEXT("ES_LEFT"),
                WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON,
                100, 120, 200, 20,
                hWnd, (HMENU)ES_LEFT1, NULL, NULL
            );
 
            CreateWindow(TEXT("button"), TEXT("ES_RIGHT"),
                WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON,
                100, 150, 200, 20,
                hWnd, (HMENU)ES_RIGHT1, NULL, NULL
            );
 
            CreateWindow(TEXT("button"), TEXT("ES_CENTER"),
                WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON,
                100, 180, 200, 20,
                hWnd, (HMENU)ES_CENTER1, NULL, NULL
            );
 
            CreateWindow(TEXT("button"), TEXT("ES_NUMBER"),
                WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON,
                100, 210, 200, 20,
                hWnd, (HMENU)ES_NUMBER1, NULL, NULL
            );
 
            
 
 
        case WM_COMMAND:
        if (wParam == ES_CENTER1) {
            
                 
                WCHAR buf[1024];        
                GetDlgItemText (hWnd, EDIT1, buf, 1024);
                SetDlgItemText(hWnd, EDIT2, buf);
                HWND hEditChild = GetDlgItem(hWnd,EDIT2);
                LONG lOldValue = GetWindowLong(hEditChild, GWL_STYLE);
                lOldValue |= ES_CENTER;
                SetWindowLong(hEditChild, GWL_STYLE, lOldValue);
                        }
 default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam); 
 
    }
    return NULL; 
}
В данном случае все работает верно, но как видите WM_COMMAND прописан только для одной кнопки, почему же копирование и применение стиля происходит при нажатии любой ?
Маленький вопрос: в чем разница между |= и просто присваиванием = ?
0
903 / 424 / 159
Регистрация: 02.04.2014
Сообщений: 1,206
19.06.2016, 11:15 12
Не знаю почему один wParam в WM_COMMAND срабатывает на все кнопки. Может быть у тебя константы их идентификаторов одинаковые? (т.е. ES_RIGHT1 == ES_CENTER1 == ES_LEFT1) ? Щелкни в коде по ним правой кнопкой, нажми "Go To Definition" и сравни значения.

"=" - это обычное присваивание, а "|=" - присваивание после побитового ИЛИ. Вот весь список: операторы присваивания

Да, и еще, попробуй кнопки создавать так: первой задай стиль группы (строка 21)
C++
1
WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | WS_GROUP
, а остальным поменяй стиль на BS_AUTORADIOBUTTON вместо BS_RADIOBUTTON
1
41 / 13 / 4
Регистрация: 22.07.2013
Сообщений: 145
19.06.2016, 12:42  [ТС] 13
Спасибо за подсказку, Действительно константы идентификаторов были одинаковые. Поменял и заработало почти как надо. Осталась одна проблема. У меня 4 кнопки - стиль по левому, правому краю, центру и в верхнем ключе.
C++ (Qt)
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
 case WM_COMMAND:
 
        if (wParam == ES_CENTER1) {
                         
                WCHAR buf[1024];        
                GetDlgItemText (hWnd, EDIT1, buf, 1024);
                SetDlgItemText(hWnd, EDIT2, buf);
                HWND hEditChild = GetDlgItem(hWnd,EDIT2);
                LONG lOldValue = GetWindowLong(hEditChild, GWL_STYLE);
                lOldValue |= ES_CENTER;
                SetWindowLong(hEditChild, GWL_STYLE, lOldValue);
                                        } 
        else 
 
        if (wParam == ES_LEFT1) {
                         
                WCHAR buf[1024];        
                GetDlgItemText (hWnd, EDIT1, buf, 1024);
                SetDlgItemText(hWnd, EDIT2, buf);
                HWND hEditChild = GetDlgItem(hWnd,EDIT2);
                LONG lOldValue = GetWindowLong(hEditChild, GWL_STYLE);
                lOldValue |= ES_LEFT;
                SetWindowLong(hEditChild, GWL_STYLE, lOldValue);
                                        } 
        else 
        if (wParam == ES_RIGHT1) {
                         
                WCHAR buf[1024];        
                GetDlgItemText (hWnd, EDIT1, buf, 1024);
                SetDlgItemText(hWnd, EDIT2, buf);
                HWND hEditChild = GetDlgItem(hWnd,EDIT2);
                LONG lOldValue = GetWindowLong(hEditChild, GWL_STYLE);
                lOldValue |= ES_RIGHT;
                SetWindowLong(hEditChild, GWL_STYLE, lOldValue);
        }
        else
                if (wParam == ES_UPPERCASE1) {
                WCHAR buf[1024];        
                GetDlgItemText (hWnd, EDIT1, buf, 1024);
                SetDlgItemText(hWnd, EDIT2, buf);
                HWND hEditChild = GetDlgItem(hWnd,EDIT2);
                LONG lOldValue = GetWindowLong(hEditChild, GWL_STYLE);
                lOldValue |= ES_UPPERCASE;
                SetWindowLong(hEditChild, GWL_STYLE, lOldValue);
        }
Программа же работает не корректно, а именно : при нажатии на кнопку ES_LEFT никуда не смещает, при нажатии на ES_RIGHT смещает влево, по центру не выставляет вообще. Верхний ключ работает всегда но после него остальные кнопки не смещают. При этом текст исправно копируется из поля в поле, только с применением стиля мешанина. Не подскажите в чем может быть дело?

Добавлено через 4 минуты
Если Создавать кнопки так:
C++ (Qt)
1
       WS_GROUP | WS_CHILD | BS_AUTORADIOBUTTON | WS_VISIBLE ,
Увы никакой разницы
0
903 / 424 / 159
Регистрация: 02.04.2014
Сообщений: 1,206
20.06.2016, 10:32 14
Лучший ответ Сообщение было отмечено Sergei12 как решение

Решение

Так происходит потому что при переключении не сбрасываются биты предыдущих стилей и они накапливаются начиная друг другу противоречить. Т.е. одновременно назначаются и ES_LEFT, и ES_RIGHT, и ES_CENTER и т.д.
Чтобы обнулить ненужные биты можно воспользоваться битовым "И" с инвертированной маской:
C++
1
lOldValue &= (~ES_RIGHT & ~ES_UPPERCASE & ~ES_CENTER);
В последнем коде все условия "if (wParam == ...)" бездумно скопированы. Весь общий код, который в них повторяется нужно вынести за скобки, что бы он не дублировался и не загромождал текст. Должна остаться только одна строка: lOldValue |= ES_....;

При создании кнопок стиль WS_GROUP должен быть только у первой. Это объединит их в группу и при нажатии в белом кружке появится черная точка.
1
41 / 13 / 4
Регистрация: 22.07.2013
Сообщений: 145
21.06.2016, 12:32  [ТС] 15
Спасибо огромное за помощь! Теперь все работает.
0
21.06.2016, 12:32
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.06.2016, 12:32
Помогаю со студенческими работами здесь

При введении значения в Edit1 и Edit5 получить с помощью расчета по формуле значение в Edit2
Всем привет! Делаю программу расчета редуктора. Возникла проблема.Необходимо при введении Значения...

ListBox+Edit1 Edit2
Есть Listbox, в котором отображается определенный столбец в базе: while NOT...

Работа с Edit1 Edit2 и CheckBox
Всем доброго времени суток. Меня заинтересовал такой вопрос, как сохранить данные в файл из Edit1 и...

Switch, зависящий не только от Edit1 но и от Edit2
Помогите с кодом что switch зависел не только от Edit1 но и от Edit2, void __fastcall...

Простая задачка edit1+edit2=Edit3
Только-только начал изучать программирования, знакомлюсь с формами, интересно стало вывести...

Массив чисел из Edit1 и Edit2 в StringGrid
Здравствуйте. Как реализовать программу: пользователь вводит начальное число в Edit1 и конечное...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru