Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Как правильно работать с функцией GetWindowText()?


Автор: Jr13san 3.3.2012, 21:06
Сколько не программирую на различных языках, но на с++ не перестаю удивляться. Иногда становится просто тошно от того, что ты знаешь как запрограммировать определённое событие, всё для этого есть, но синтаксис не позволяет тебе двигаться дальше. Такая же ситуация и здесь.
Пересмотрел пару десятков примеров вызова функции GetWindowText(), но ни один не работает.
У меня есть только предположение о том, что я что-то упустил. Я сомневаюсь, что те части кода были обманом. Поэтому прошу помочь разобраться.

Код

void main()//главная функция, загружается самая первая
{
    setlocale(LC_ALL, "Russian");//устанавливаем русский язык для вывода информации на экран
    HWND hWnd = FindWindow(NULL, TEXT("Безымянный - Блокнот"));//получаем хэндл открытого окна Блокнота
    TCHAR wName[255];
    GetWindowText(hWnd, wName, 255);//по идее отправляем в переменную "wName" заголовок окна Блокнота
    printf("%s",wName);
}


Ещё получилось выцепить ASCII символы из строки. Сейчас я не помню как тогда я написал. Но пришлось бы изобретать функцию преобразования всего этого в строку. А зачем передавать строку в непонятном виде, чтобы её нужно было потом преобразовывать? И это называется упрощение работы программисту? Даже нет слов. И грустно и смешно...

Почему разработчики не могли сделать такую конструкцию? :
Код

char wName;
wName = GetWindowText(hWnd);//получаем полный заголовок по хэндлу окна
printf("%s",wName);

Наверное понравилось извращаться с переправкой данных за место того, чтобы этим занимался программист. Зачем наделали столько типов, что приходится на каждый вызов функции преобразовывать её выходные данные. Неужели нельзя было обойтись стандартными типами: short, int, long, byte, bool, string, double, и т.д. Зачем больше? Вместо того, чтобы работать над программным кодом, мне приходится искать преобразование типов или узнавать что это за таинственные типы параметров, передающихся в вызываемую функцию. Язык должен быть интуитивно понятным и простым в освоении, а не извращённым до нельзя.

Результат самостоятельной работы над ошибками:
Так как в проекте используется поддержка Unicode строк, то код выглядит следующим образом:

Код

//Включаем заголовочные файлы в проект
#include <windows.h>//для использования Windows API функций
#include <sstream>//для функции printf и настройки языка вывода в окно консоли

void main()//главная функция, загружается самая первая
{
    setlocale(LC_ALL, "Russian");//устанавливаем русский язык для вывода информации на экран
    HWND hWnd = FindWindow(NULL, TEXT("Безымянный - Блокнот"));//получаем хэндл открытого окна Блокнота
    
    wchar_t wName[21];//резервируем место под название окна (ровно 21 символ для заранее известного названия: "Безымянный - Блокнот")
    wchar_t wName2[21] = L"Безымянный - Блокнот";//вторая юникод-строка для сравнения с полученной юникод-строкой от функции GetWindowText()
    GetWindowText(hWnd, (LPTSTR)wName, 21);//вызываем функцию получения заголовка окна по хэндлу(hWnd). Результат уйдёт в "wName" в качестве юникодной строки. Из заголовка берём 21 символ.
    
    if (CompareStringW(LOCALE_INVARIANT,0, wName, -1, wName2, -1) == CSTR_EQUAL)//если юникод-строки: wName и wName2 равны, то
    {
        printf("%s\n", "Строки равны.");
    }
    else//иначе
    {
        printf("%s\n", "Строки различны.");
    }
}


Чтобы проверить результат работы программы, нужно открыть окно блокнота(Notepad.exe) и  запустить программу.
Результат работы программы таков:
1. Получить идентификатор заголовка окна Блокнота.
2. По идентификатору окна получить обратно название окна.
3. Сравнить полученное название окна с заранее известным названием окна.

Автор: LeonidPr 3.3.2012, 21:34
А какое отношение к C++ имеет функция GetWindowText?
Это одна из функций API в Windows, а в хедэре просто описан
её прототип, чтобы вы могли её вызывать.
Если бы Microsoft сделала эту функцию такой:
Код

char *GetWindowText(HWND hWnd);

то использовали бы её так, как вы написали:
Код

wName = GetWindowText(hWnd);

Мне кажется (знатоки, поправьте пожалуйста, если я не прав), что первый вариант был выбран из тех соображений, что вы должны будете явно выделить буфер для строки и следовательно будете следить, что бы память была освобождена после использования. Во втором же случае, система сама неявно (для того, кто пользуется функцией) должна выделить память под возвращаемую строку. Следовательно, легко забыть освободить её, что может привести к неприятностям.

Автор: Jr13san 3.3.2012, 22:00
А что тут очищать то? Может быть ещё вручную?
Я думаю так..
Функция возвращает "текст", а все переданные в неё параметры должны по идее сами удалиться из памяти после завершения работы этой функции. Но для этого должен существовать определённый "чистильщик". Или я не правильно мыслю в силу других языков, работающих таким алгоритмом?

Автор: boostcoder 3.3.2012, 22:13
Цитата(Jr13san @  3.3.2012,  21:06 Найти цитируемый пост)
синтаксис не позволяет тебе двигаться дальше

причину нужно искать в себе.
плохому танцору, в курсе что мешало? ;)

Цитата(Jr13san @  3.3.2012,  21:06 Найти цитируемый пост)
Почему разработчики не могли сделать такую конструкцию?

тебе не понять.
к тому же, там ошибка.

в общем, тему на свалку.

Автор: LeonidPr 3.3.2012, 22:15
Что бы функция вернула текст, она должна выделить память под него. Вы с этим текстом поработали (вывели на консоль например). Теперь надо освободить выделенную под него память. Кто это будет делать? Я так понимаю вы, в C++ нет стандартного сборщика мусора.

Автор: boostcoder 3.3.2012, 22:18
Цитата(LeonidPr @  3.3.2012,  21:34 Найти цитируемый пост)
вы должны будете явно выделить буфер для строки и следовательно будете следить, что бы память была освобождена после использования.

угу. правило такое есть: память нужно освобождать на то же уровне, на котором она была выделена.

Цитата(Jr13san @  3.3.2012,  22:00 Найти цитируемый пост)
Функция возвращает "текст"

нет такого типа smile 

Цитата(Jr13san @  3.3.2012,  22:00 Найти цитируемый пост)
 все переданные в неё параметры должны по идее сами удалиться из памяти

страшно жить.

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

Цитата(Jr13san @  3.3.2012,  22:00 Найти цитируемый пост)
я не правильно мыслю

есть такое мнение среди программистов: после изучения языка "Х", моцг напрочь отказывается самостоятельно мыслить.

Автор: Jr13san 3.3.2012, 22:43
Цитата(boostcoder @  3.3.2012,  22:13 Найти цитируемый пост)
причину нужно искать в себе.

Как раз-таки здесь причина в самом языке программирования.

Цитата(boostcoder @  3.3.2012,  22:13 Найти цитируемый пост)
тебе не понять.
к тому же, там ошибка.

Скорей всего тебе не понять мою мысль.
И вот наверное твоя же фраза это подтверждает:
Цитата(boostcoder @  3.3.2012,  22:18 Найти цитируемый пост)
есть такое мнение среди программистов: после изучения языка "Х", моцг напрочь отказывается самостоятельно мыслить.
 

Цитата(boostcoder @  3.3.2012,  22:13 Найти цитируемый пост)
в общем, тему на свалку. 

Ага, куда же ей ещё. Жди, сейчас мусоровоз подъедет.
Если тебе тема не интересна, то это не значит, что всё тут напрасно.
Я пытаюсь разобраться с помощью людей, которые разбираются в данном языке и готовы как-то помочь. А от тебя одни сплошные комментарии, а толку 0.

Цитата(LeonidPr @  3.3.2012,  22:15 Найти цитируемый пост)
Что бы функция вернула текст, она должна выделить память под него. Вы с этим текстом поработали (вывели на консоль например). Теперь надо освободить выделенную под него память. Кто это будет делать? Я так понимаю вы, в C++ нет стандартного сборщика мусора. 

Даже если этого сборщика нет, это не беда, это лишь отсутствие автоматизации данного языка.
Дело в том, что функция возвращает не пойми что. Попробуйте написать что-то работающее на основе того, что я написал.

Цитата(boostcoder @  3.3.2012,  22:18 Найти цитируемый пост)
нет такого типа

в c++ может быть и нет, но в других ЯП есть тип string и он на много удобнее и проще чем char, TCHAR, WCHAR, ZLUPECHAR. Извините за последний "агрессивно-вымышленный" тип, но таковы реалии.

Автор: bems 3.3.2012, 22:45
Цитата(Jr13san @  3.3.2012,  22:43 Найти цитируемый пост)
Как раз-таки здесь причина в самом языке программирования.
в данном случае нет, но дело даже не в этом. Если тебе не нравится язык, зачем ты на нём пишешь?

Автор: boostcoder 3.3.2012, 22:52
Цитата(Jr13san @  3.3.2012,  22:43 Найти цитируемый пост)
в c++ может быть и нет, но в других ЯП есть тип string

тот код что ты привел - Си. в с++ как раз таки строки есть.
это лишнее подтверждение моих слов smile 

так на каких ты там языках пишешь?

Автор: Jr13san 3.3.2012, 22:56
Цитата(bems @  3.3.2012,  22:45 Найти цитируемый пост)
в данном случае нет, но дело даже не в этом. Если тебе не нравится язык, зачем ты на нём пишешь?

Вы сговорились что-ли все?
На самом деле я пишу на c++ из за его высокой скорости и относительно быстрой скорости написания кода в отличии от asm.

Автор: boostcoder 3.3.2012, 22:57
Цитата(Jr13san @  3.3.2012,  22:43 Найти цитируемый пост)
И вот наверное твоя же фраза это подтверждает

ты не понимаешь одну из основ самосовершенствования: критика всего вокруг себя но только не себя - обрекает тебя на постоянное совершение того, что ты сейчас делаешь. а именно - говорить что что-то не так и не эдак, вместо того чтоб признать, что ты банально читать не умеешь. ибо для этой функции есть дока, и любой адекватный человек, за несколько минут разберется с тремя аргументами.

по этому, снова спрошу: плохому танцору, знаешь что мешает?

Добавлено @ 22:58
Цитата(Jr13san @  3.3.2012,  22:56 Найти цитируемый пост)
 я пишу на c++

для танкистов, повторяю: это Си!

Автор: marsh123 3.3.2012, 22:58
Сообщил в Microsoft гениальную идею автора, пообещали, что исправят.  smile 

Автор: boostcoder 3.3.2012, 23:02
marsh123, сообщи ТСу адресок. чтоб в следующий раз он сразу им писал smile 

Автор: Jr13san 3.3.2012, 23:03
Ок. Я так понял, помощи я здесь не найду.
Прощу прощение у адм. за пустую созданную тему.

Автор: bems 3.3.2012, 23:04
Цитата(Jr13san @  3.3.2012,  22:56 Найти цитируемый пост)
Вы сговорились что-ли все?
На самом деле я пишу на c++ из за его высокой скорости и относительно быстрой скорости написания кода в отличии от asm. 
не, если хорошо порыться в этом разделе то можно видеть как я тоже критикую плюсики. так что с ними точно не сговаривался.
А скорость написания выше разве что по сравнению с асмом, лол. Нет никаких причин писать user-mode приложения для windows на плюсах или чистом си. Это не нужно, для этого есть более удобные инструменты.

А проблема описанная в оппосте связана даже не с языком, а с тем что ты не въехал в винапи, но пытаешься его использовать. Он совершенно сишный, со всей вытекающей ручной работой

Автор: marsh123 3.3.2012, 23:04
Цитата(boostcoder @ 3.3.2012,  23:02)
marsh123, сообщи ТСу адресок. чтоб в следующий раз он сразу им писал smile

Как Вы, кстати, определили, что тс пишет на Си, просто интересно, такой код без проблем и на C++ должен работать.
Неужели из-за того, что он printf использует?

Автор: boostcoder 3.3.2012, 23:09
потому что в его коде нет ничего от плюсов.

Добавлено через 1 минуту и 16 секунд
на каких языках ТС профессионально пишет, нам не удастся узнать. ТС обиделся и нас покинул. вовсе.

Автор: LeonidPr 3.3.2012, 23:13
Ух-ты, отошел от компа минут на десять, а тут такой спор...
Так вот, Jr13san, я так до конца не понял, к чему конкретно ваша претензия?
Если к языку, тогда причем здесь GetWindowText - это к WinAPI,
если к GetWindowText, тогда причем здесь C++?
Если вам не нравится, как ведет себя GetWindowText, предлагаю написать функцию-обертку, которая будет выдавать вам результат в том
виде, в каком вам хочется. Может вернуть char*, может string.
Вы напишите конкретно, в чем вопрос, может сможем помочь...

Автор: bsa 3.3.2012, 23:14
Jr13san, ты языка то не знаешь. Во-первых, обозвал язык С языком С++. Во-вторых, удивительно, как у тебя программа вообще компилируется, так как "главная функция, загружается самая первая" обязана возвращать int. В-третьих, ты вляпался в WinAPI и клянешь язык. Ты не думал, что printf работает исключительно с char. А с TCHAR работает _tprintf. Так как TCHAR в зависимости от настроек проекта может быть как char, так и wchar_t.

Добавлено через 5 минут и 4 секунды
Цитата(Jr13san @  3.3.2012,  22:06 Найти цитируемый пост)
Зачем наделали столько типов, что приходится на каждый вызов функции преобразовывать её выходные данные. Неужели нельзя было обойтись стандартными типами: short, int, long, byte, bool, string, double, и т.д. Зачем больше?
Затем, чтобы было проще. HWND несет больше смысла, чем void*. А DWORD гарантирует 32-хбитность. В С99, кстати, были введены аналогичные типы: uint8_t, uint16_t, uint32_t, uint64_t...

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