Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > [CE] Получить текст из объекта класса PIEHTML


Автор: ksili 16.12.2009, 09:56
Мне надо получить текст из одного приложения. На нём находится окно с именем класса DISPLAYCLASS, на нём в свою очередь окно с именем класса PIEHTML. Вот из него мне и нужен текст. HWND этого окна я получаю. Но вот GetWindowText возвращает пустую строку. Как получить текст из этого хитрого контрола? Насколько я понял, это контрол для отображения форматированного текста. На окне как раз такой и отображается.

Вообще, у приложения Remote Spy находит ещё пару контролов, но они либо отображаются в нём без текста (как и PIEHTML), либо не с тем текстом, который мне нужен. Так что я предположил, что нужный мне текст как раз и прячется где-то в недрах PIEHTML.

Это всё под Windows Mobile 6.1. Но полагаю, что здесь ничего специфического для него нет.

Автор: GremlinProg 16.12.2009, 12:00
Цитата(ksili @  16.12.2009,  11:56 Найти цитируемый пост)
Но вот GetWindowText возвращает пустую строку

GetWindowText работает только в своем процессе, пробуй посылать WM_GETTEXT через SendMessage
Цитата(GetWindowText @  MSDN)

When working with RAPI for Windows CE 1.0 and 1.01, use the PegGetWindowText function.

If the target window is owned by the current process, GetWindowText causes a WM_GETTEXT message to be sent to the specified window or control. If the target window is owned by another process and has a caption, GetWindowText retrieves the window caption text. If the window does not have a caption, the return value is a null string. 


Цитата(ksili @  16.12.2009,  11:56 Найти цитируемый пост)
Насколько я понял, это контрол для отображения форматированного текста. На окне как раз такой и отображается.

в принципе, чтобы показать форматированный текст не обязательно пользоваться особыми контролами,
это может быть и простое окно ( в WM, насколько знаю, RichEdit вообще отсутствует, это и есть та специфичная разница )

Автор: ksili 16.12.2009, 12:07
Я уже разобрался, что данный контрол имеет свом специфичные сообщения, описанные в Htmlctrl.h. Сначала сообщением DTM_SELECTALL контролу DISPLAYCLASS выделяем весь текст (это работает - видно на экране), а потом его можно весь скопировать в поток сообщением DTM_COPYSELECTIONTONEWISTREAM. Но почему-то поток так и остается пустой. Пробовал его посылать и в DISPLAYCLASS и в PIEHTM.

Беда ещё в том, что сообщение DTM_COPYSELECTIONTONEWISTREAM вообще не документировано. 

Вот код, может ошибки увидите:
Код

HWND child = FindChildWindow(L"DISPLAYCLASS", L"", dialog);
if(child)
{
    wchar_t sb[256];
    DWORD rsd = 0;
    LPSTREAM pStream = 0;
    wchar_t gettext[256];
    wstring ussdAnswer;
    LPWSTR pSelectedText;

    ::SendMessage(child, DTM_SELECTALL, 0, 0);
    ::SendMessage(child, DTM_COPYSELECTIONTONEWISTREAM, (WPARAM)&rsd, (LPARAM)&pStream);
    if( pStream )
    {
                        // сюда пока вообще не попадаем
        STATSTG stat = { 0 };
        if (SUCCEEDED(pStream->Stat(&stat, STATFLAG_NONAME)))
        {
            ULONG ulNumChars = 0;
            pSelectedText = (LPWSTR)LocalAlloc(LPTR,(ULONG)stat.cbSize.QuadPart + 8); 

            if (pSelectedText)
            {
                HRESULT hr = pStream->Read(pSelectedText,(ULONG)stat.cbSize.QuadPart, &ulNumChars);

                if( SUCCEEDED(hr) )
                {
                    // парсим текст
                }

                LocalFree(pSelectedText);
            }
        }

        pStream->Release ();
    }
    trace(g_bLog, L"   USSD answer - %s\n", pSelectedText);
}

Автор: GremlinProg 16.12.2009, 12:18
Цитата

DTM_COPYSELECTIONTONEWISTREAM does work on WM5. It should be sent to the window handle which created by “Create( DISPLAYCLASS, ….)”. But unforturnately, it dosen’t work under WM6 for unknow reason.

http://dalelane.co.uk/blog/?p=191
можно попробовать через буфер обмена

Автор: ksili 16.12.2009, 12:23
Цитата(GremlinProg @ 16.12.2009,  16:18)
Цитата

DTM_COPYSELECTIONTONEWISTREAM does work on WM5. It should be sent to the window handle which created by “Create( DISPLAYCLASS, ….)”. But unforturnately, it dosen’t work under WM6 for unknow reason.

GremlinProg, там же ниже написано:

Цитата

Sorry, Looks like the DTM_COPYSELECTIONTONEWISTREAM works under WM6, it’s some other bugs cause the my program out of work.

Автор: ksili 16.12.2009, 13:12
Пробую через буфер обмена. После выделения текста посылаю WM_COPY. Потом пробую GetClipboardData с параметром CF_TEXT или CF_UNICODETEXT. Всегда возвращается нулевой хэндл.

Хочу ещё попробовать просто слать нажатие на Ctrl+C. Подскажите как это проще сделать на чистом API.

Автор: GremlinProg 16.12.2009, 13:17
а фокус стоит на контроле перед копированием?
Код

::SetFocus( hwndViewer );

Автор: GremlinProg 16.12.2009, 13:32
если WM_COPY не срабатывает, значит и результат от Ctrl+C скорее будет таким же
текст вообще копируется в буфер обмена, вживую?
если да, то WM_COPY тут ни при чем, смотри за работой с буфером обмена, может еще и с выделением

лучше конечно не пинать воздух, а смотреть на конкретный код

Автор: ksili 16.12.2009, 13:34
Это идея.

::SetFocus возвращает ERROR_INVALID_WINDOW_HANDLE. Хотя перед этим по этому же хэндлу нормально выделяется весь текст.

Добавлено через 3 минуты и 4 секунды
Цитата(GremlinProg @  16.12.2009,  17:32 Найти цитируемый пост)
текст вообще копируется в буфер обмена, вживую?

Это всё на девайсе происходит. Кнопки Ctrl тут нет. Контекстного меню у данного окна тоже не вылазит. Так что чёрт его знает.

Автор: ksili 16.12.2009, 13:51
А вот в коде из самого первого поста нету случайно ошибки в следующих строках?
Код

LPSTREAM pStream = 0;
::SendMessage(child, DTM_COPYSELECTIONTONEWISTREAM, (WPARAM)&rsd, (LPARAM)&pStream);


Я раньше с такими потоками не работал. Может там ещё память выделять надо?

Автор: GremlinProg 16.12.2009, 13:52
Цитата(ksili @  16.12.2009,  15:34 Найти цитируемый пост)
ERROR_INVALID_WINDOW_HANDLE

это он так скорее всего на чужой поток ругается,
поставить фокус в чужое окно можно только между AttachThreadInput,
но я не вижу ее в CE, вижу только упоминание: http://msdn.microsoft.com/en-us/library/ms961490.aspx

Добавлено через 5 минут и 27 секунд
Цитата(ksili @  16.12.2009,  15:51 Найти цитируемый пост)
А вот в коде из самого первого поста нету случайно ошибки в следующих строках?

вообще может, но без документации можно предположить, что pStream инициализируется в ответ на сообщение,
поэтому и передается по ссылке

Добавлено через 6 минут и 18 секунд
т.е. вполне возможно, что ошибок там нет, особенно после забега в гугл

Автор: ksili 19.12.2009, 18:35
В общем, похоже я всё делал правильно. Проблема скорее всего в девайсе (Samsung SGH-i900 WiTu), а точнее специфическом ПО на нём, от производителя. Они там вроде так специально сделали, чтобы нельзя было программно читать ответы на USSD-запросы. Знаю одну программу, которая эту проблему обошла, но они там вроде что-то в системных файлах подменяют. 

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