Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» C++ WinAPI

Автор: Abs62
Дата сообщения: 05.12.2010 15:21
stazher

Цитата:
Но чем можно заменить функцию ExtractFileName которая AnsiString - непонятно.

Посмотри PathFindFileName.
Автор: V0lt
Дата сообщения: 09.12.2010 08:21
Ковыряю код. В обработчике OnToolTipNotify вижу продублированные структуры:
TOOLTIPTEXTA, TOOLTIPTEXTW;
TTN_NEEDTEXTA, TTN_NEEDTEXTW.

В одном из примеров видел тоже самое но без суффиксов A и W:
TOOLTIPTEXT, TTN_NEEDTEXT.

Я так понимаю A = ANSI, W = UNICODE. А для чего структуры без суффиксов?

Если я пишу для Windows XP и выше, то я могу обойтись без дублирования? Если да, то какого вида из трех структур нужно использовать?
Автор: Abs62
Дата сообщения: 09.12.2010 16:33
V0lt

Цитата:
А для чего структуры без суффиксов?

Они раскрываются в ANSI или UNICODE при компиляции. Вот кусочек из commctl.h:

Код: #define TOOLTIPTEXT NMTTDISPINFO
...
#ifdef UNICODE
#define NMTTDISPINFO NMTTDISPINFOW
#define LPNMTTDISPINFO LPNMTTDISPINFOW
#define NMTTDISPINFO_V1_SIZE NMTTDISPINFOW_V1_SIZE
#else
#define NMTTDISPINFO NMTTDISPINFOA
#define LPNMTTDISPINFO LPNMTTDISPINFOA
#define NMTTDISPINFO_V1_SIZE NMTTDISPINFOA_V1_SIZE
#endif
Автор: V0lt
Дата сообщения: 09.12.2010 18:33
Abs62
Тогда такой вопрос. Струтуры с суффиксом A (ANSI) нужны толькр для работы в Win98? На WinXP без них можно?
Автор: Garrett
Дата сообщения: 09.12.2010 18:56
V0lt
У тебя может быть скомпилировано и не юникодное приложение, и оно тоже будет нормально работать в WinXP.
Автор: Abs62
Дата сообщения: 09.12.2010 19:02
V0lt
Зачем программисту ANSI-структуры и функции, должен сказать он сам. Мало ли, может надо файл прочитать, в котором такая ANSI-структура записана, к примеру. Или с другой программой пообщаться, которая юникод не понимает. Или просто привычнее ему так. Но если каких-то особых причин нет, то вполне резонно работать именно в юникоде.
Автор: V0lt
Дата сообщения: 09.12.2010 19:39
Abs62

Цитата:
Но если каких-то особых причин нет, то вполне резонно работать именно в юникоде

Вообщем весь проект как бы в уникоде, но в некоторых местах есть такие дубли. Я только что спросил: стоит ли мне тоже дублировать. Мне сказали, что не надо, попробуй сделать только в уникоде и посмотри, что получиться
Автор: V0lt
Дата сообщения: 08.02.2011 21:20
Есть CSliderCtrl.
Как узнать растояние между начальным и конечным положениями в пикселях?
Всю документацию по CSliderCtrl уже перерыл, нет ничего подобного.
Автор: Abs62
Дата сообщения: 08.02.2011 23:15
V0lt
А GetChannelRect - это не то?
Автор: V0lt
Дата сообщения: 09.02.2011 05:56
Похоже, но измерения показали что ChannelRect выдает значения немного больше реального хода ползунка.
Как узнать или посчитать точную длину хода ползунка?
Автор: Abs62
Дата сообщения: 09.02.2011 07:55
V0lt

Цитата:
ChannelRect выдает значения немного больше реального хода ползунка

Случаем, не на ширину ползунка больше?
Автор: V0lt
Дата сообщения: 09.02.2011 16:30
Похоже на то
спасибо.
Автор: V0lt
Дата сообщения: 10.02.2011 22:28
Подскажите, как узнать положение и размер прямоугольника обычного текста (CTEXT)?
Автор: Abs62
Дата сообщения: 10.02.2011 22:38
V0lt
Имеется в виду элемент диалога? Тогда можно через GetWindowRect(GetDlgItem()).
Автор: V0lt
Дата сообщения: 11.02.2011 06:10
Да обычный текст.

Задача в следующем. На диалоге есть текст
CTEXT "Balance",IDC_STATIC_BALANCE,180,19,75,8
Надо обработать двойной клик по этому тесту.
Сейчас есть такой обрабочик:

Код: void CPPagePlayback::OnLButtonDblClk(UINT nFlags, CPoint point)
{
    if (???)
        m_balancectrl.SetPos(0);
}
Автор: Abs62
Дата сообщения: 11.02.2011 08:19
V0lt
Ну, как-нибудь так:

Код: CWnd *h=ChildWindowFromPoint(point);
if(h!=NULL && h->GetDlgCtrlID() == IDC_STATIC_BALANCE)
Автор: V0lt
Дата сообщения: 11.02.2011 19:41
Abs62
В последнем примере условие не срабатывает. У меня сомнения, что в h передается ID нужной строки теста.


Цитата:
Тогда можно через GetWindowRect(GetDlgItem())

А можно чуток подробнее.
Автор: Abs62
Дата сообщения: 11.02.2011 20:00
V0lt

Цитата:
У меня сомнения, что в h передается ID нужной строки теста.

Здесь несколько по-другому делается. Ищется окно, которому принадлежит заданная точка, а потом его ID сравнивается с искомым.

Цитата:
А можно чуток подробнее.


Код: CRect r;
CWnd *h=GetDlgItem(IDC_STATIC_BALANCE);
if(h!=NULL) {
h->GetWindowRect(&r);
if(r.PtInRect(point)) ...
}
Автор: V0lt
Дата сообщения: 11.02.2011 21:20
Abs62
Возможно я тебя немного запутал, поэтому немного пояснений.
PPagePlayback часть окна настроек. Текст IDC_STATIC_BALANCE находится на ней.

Нужно по двойному клику на "Balance" изменить положение нижележащего ползунка.

CPPagePlayback::OnLButtonDblClk срабатывает по двойному клику. point выдает координаты курсора внутри PPagePlayback.

h->GetWindowRect(&r);
В r у меня получаются координаты и размеры той части окна, в которой находится PPagePlayback. Я щелкаю по любому тексту, r естественно всегда одинаковая пока само окно не сдвинешь.
Вообщем метод с GetWindowRec тут не работает

С вариантом ChildWindowFromPoint аналогично. Есть ощущение, что Window в названии функций не зря указан.
Автор: Abs62
Дата сообщения: 11.02.2011 22:07
V0lt

Цитата:
Возможно я тебя немного запутал, поэтому немного пояснений.

Да я уж догадался, о чём речь.

Цитата:
h->GetWindowRect(&r);
В r у меня получаются координаты и размеры той части окна, в которой находится PPagePlayback.

Должны быть координаты элемента "CTEXT "Balance"...". Для того и делается CWnd *h=GetDlgItem(IDC_STATIC_BALANCE).

Цитата:
Я щелкаю по любому тексту, r естественно всегда одинаковая пока само окно не сдвинешь.

Само собой. Элемент-то по окну не ползает, это point меняется.

Цитата:
Вообщем метод с GetWindowRec тут не работает

Не попадает в окно или всегда попадает?
Пересчитать point в экранные координаты не забыл? Она ж в оконных координатах в OnLButtonDblClk подаётся.

Код: ClientToScreen(&point);
Автор: V0lt
Дата сообщения: 13.02.2011 08:46
Abs62
Метод с ChildWindowFromPoint дает такой прямоугольник
r1    {top=323 bottom=417 left=716 right=1145}
он неправильный. Если сделать ClientToScreen(&point), то вообще не работает.

Метод с GetDlgItem после ClientToScreen(&point) выдает такой прямоугольник
r2    {top=346 bottom=359 left=978 right=1091}
Он правильный (113x13) , тоже самое выдает плагин Task Manager в Total Commander.

Хотя в ресурсах указано 75x8 и откуда взялось 113x13, я чего-то не догнал

вот рабочий код:

Код: void CPPagePlayback::OnLButtonDblClk(UINT nFlags, CPoint point)
{
    ClientToScreen(&point);
    CWnd *h=GetDlgItem(IDC_STATIC_BALANCE);
    if(h!=NULL)    {
        CRect r;
        h->GetWindowRect(&r);
        if(r.PtInRect(point)) {
            m_balancectrl.SetPos(100);
            SetModified();
        }
    }
}
Автор: Abs62
Дата сообщения: 13.02.2011 12:10
V0lt

Цитата:
Хотя в ресурсах указано 75x8 и откуда взялось 113x13, я чего-то не догнал

В ресурсах размеры элементов указываются не в пикселях, а в DTU - dialog template units. При отображении диалога система пересчитывает их в пиксели с учётом заданного в шаблоне диалога шрифта. Смотри How to calculate dialog box units based on the current font in Visual C++.
Автор: V0lt
Дата сообщения: 14.02.2011 19:04
Abs62
Все равно не догнал откуда лишние 38(!) пикселей по ширине, ну да ладно.

Есть другая проблема. Есть слайдер ориентированный горизонтально. Выбираю его, делаю прокрутку мышью. Кручу верх, слайдер едет влево, вниз - вправо! Какой гад так сделал? И даже опции не оставил, чтобы поменять такое несуразное поведение!
Есть решение?
Автор: Abs62
Дата сообщения: 14.02.2011 19:29
V0lt

Цитата:
Какой гад так сделал?

Bill Gates.

Цитата:
Есть решение?

Задай ему стиль TBS_DOWNISLEFT.

Цитата:
TBS_DOWNISLEFT
By default, the trackbar control uses down equal to right and up equal to left. Use the TBS_DOWNISLEFT style to reverse the default, making down equal left and up equal right.
Автор: V0lt
Дата сообщения: 14.02.2011 20:09

Цитата:
Задай ему стиль TBS_DOWNISLEFT.

Спасибо. В редакторе ресурсов такого нет . Я сам только эту опцию нашел с большим трудом. Решение, как я понял, не всегда помогает, но у меня работает без проблем.

Еще вопрос.
Допустим на левой кнопке мыши сидит некоторая команда. Я нажимаю правую кнопку, выходит контекстное меню. Нажимаю левую в произвольном месте (чтобы не выбирать никакой пункт меню и закрыть его), меню исчезает и срабатывает команда. А мне не надо чтобы команда в этом случае срабатывала.
1. Можно ли определить, вызвано ли в текущий момент контекстное меню? Т.е. если вызвано, то команду не выполнять. (Есть конечно подозрение, что во время проверки меню уже исчезнет и толку будет ноль)
2. Можно ли сделать свой обработчик, на закрытие меню? Чтобы в этом обработчике прибить событие вызвавшее его, т.е. никуда дальше нажатие ЛКМ не отправлять. Или это нереально?
Автор: Abs62
Дата сообщения: 14.02.2011 21:09
V0lt
Да нету такого события - "закрытие меню". Вся обработка идёт внутри API-функции TrackPopupMenu.
Разве что попробовать после возврата из неё (прямо в обработчике WM_RBUTTONDOWN) выдернуть из очереди сообщений WM_LBUTTONDOWN, если оно там есть.

Код: MSG msg;
PeekMessage(&msg, hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE);
Автор: asi81
Дата сообщения: 15.02.2011 17:01
Добрый день!

Казалось бы тривиальная задача. Но не могу чтото сразу найти.

Я в своем приложении запускаю CreateProcess -- cmd /c anyscript.bat и в создаю три пайпа для стандартных потоков вывода ввода и ошибок.

STARTUPINFO start;
CreatePipe(&ReadPipe, &start.hStdOutput,&Security, 0);
CreatePipe(&start.hStdInput, &WritePipe,&Security, 0);
CreatePipe(&ErrorPipe,&start.hStdError, &Security, 0));

Когда скрипт выполняется я должен из него получать текстовый вывод и печатать его в своей программе. Вопрос - как мне сделать так, чтобы читать потоки hStdOutput и hStdError в правильном порядке. тоесть выводить текстовую инфу в свое окно в том порядке, в котором она появлялась в cmd.exe.

Можно сделать проще, не делать отдельный пайп для потока ошибок, а приравнять hStdError к hStdOutput в STARTUPINFO, но я хотел бы показывать цветом, какая информация была из обычного выходного потока, а какая из потока ошибок.


Автор: Abs62
Дата сообщения: 15.02.2011 17:51
asi81
Может, проверять в цикле наличие данных в том и другом пайпе через PeekNamedPipe? Где данные появились - там и читать.
Автор: V0lt
Дата сообщения: 15.02.2011 18:30
Abs62
Поставил в функцию OnMenu сразу после вызова TrackPopupMenu, вместо hWnd написал NULL (правильно ведь?). Вроде работает. Потестю немного...

Если я кроме WM_LBUTTONDOWN захочу обрать другие сообщения, мне надо несколько раз запускать PeekMessage? Там есть маски, но это больше похоже на начало и конец диапазона сообщений.
Автор: Abs62
Дата сообщения: 15.02.2011 18:49
V0lt

Цитата:
вместо hWnd написал NULL (правильно ведь?)

Это означает прошерстить все очереди текущего потока, не только для конкретного окна. По идее можно и так, все равно больше одного WM_LBUTTONDOWN в них быть не должно.

Цитата:
Если я кроме WM_LBUTTONDOWN захочу обрать другие сообщения, мне надо несколько раз запускать PeekMessage?

Угу.

Цитата:
Там есть маски, но это больше похоже на начало и конец диапазона сообщений.

Именно так, PeekMessage ищет сообщения заданного диапазона. Но вытаскивает всё равно одно сообщение за раз. Первое подходящее под условия.

Страницы: 12345678910111213141516171819202122232425262728293031323334353637

Предыдущая тема: посоветуйте книги по SQL


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.