Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Правильно получение Extended Window Styles


Автор: ecspertiza 19.11.2013, 15:04
Собственно вопрос, как правильно получить Extended Window Styles из HWND окна ? На данный момент у меня стоит задача отловить все скролищиеся окна в системе, пока делаю так 

Код

std::string indent = "";

void wstring_to_string(const std::wstring& src, std::string& dest)
{
    std::string tmp;
    tmp.resize(src.size());
    std::transform(src.begin(),src.end(),tmp.begin(),wctob);
    tmp.swap(dest);
}

std::string convert(LPWSTR str) {
    std::string res;
    wstring_to_string(std::wstring(str),res);
    return res;
}

static BOOL CALLBACK EnumWindowsChildProc(HWND hwnd, LPARAM lParam) {
  TCHAR buff[100];
  int resC = GetClassName(hwnd,buff, 100);
  if (resC == 0) {
      std::cout << "EnumWindowsChildProc " << resC << " " << GetLastError() << std::endl;
      return FALSE;
  }

  std::string clName = convert(buff);

  WINDOWINFO pwi;
  GetWindowInfo(hwnd, &pwi);

  if (((pwi.dwStyle & WS_HSCROLL) || (pwi.dwStyle & WS_VSCROLL)) || ((pwi.dwExStyle & WS_EX_LEFTSCROLLBAR) || (pwi.dwExStyle & WS_EX_RIGHTSCROLLBAR))) {
      std::cout << "find fucking scroll" << std::endl;
  }

  long resEx = GetWindowLong(hwnd, GWL_EXSTYLE);
  if (((resEx & WS_EX_LEFTSCROLLBAR) || (resEx & WS_EX_RIGHTSCROLLBAR))) {
      std::cout << "find fucking scroll" << std::endl;
  }

//  std::cout << indent.c_str() << "class name " << clName.c_str() << std::endl;

  indent += "  ";
  EnumChildWindows(hwnd, (WNDENUMPROC)EnumWindowsChildProc, NULL);
  return TRUE;
}

static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
  
  TCHAR buff[100];
  int resC = GetClassName(hwnd,buff, 100);
  if (resC == 0) {
      std::cout << "EnumWindowsProc " << resC << " " << GetLastError() << std::endl;
      return FALSE;
  }

  std::string clName = convert(buff);

  LPWSTR pszMem;
  int length = GetWindowTextLength(hwnd);

  pszMem = (LPWSTR) VirtualAlloc((LPVOID) NULL,
              (DWORD) (length + 1), MEM_COMMIT,
              PAGE_READWRITE);

  GetWindowText(hwnd, pszMem, length + 1);

  std::string title = convert(pszMem);

  if (IsWindowVisible(hwnd) && !title.empty()) {
      std::cout << "title " << title.c_str() << std::endl;
      indent = "  ";
      EnumChildWindows(hwnd, (WNDENUMPROC)EnumWindowsChildProc, NULL);
  }

  return TRUE; // continue enumeration
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::cout << "-------------------------------------" << std::endl;
    HWND hd = GetDesktopWindow();

    EnumWindows((WNDENUMPROC)EnumWindowsProc, NULL);

    while(1){
        Sleep(1000);
    }

    return 0;
}



пробегаю по всем окнам, затем смотрю их детей и ищю те компоненты которые будут скролиться, на сам скролл проверяю так

Код


WINDOWINFO pwi;
GetWindowInfo(hwnd, &pwi);

if (((pwi.dwStyle & WS_HSCROLL) || (pwi.dwStyle & WS_VSCROLL)) || ((pwi.dwExStyle & WS_EX_LEFTSCROLLBAR) || (pwi.dwExStyle & WS_EX_RIGHTSCROLLBAR))) 


и так

Код

long resEx = GetWindowLong(hwnd, GWL_EXSTYLE);
  if (((resEx & WS_EX_LEFTSCROLLBAR) || (resEx & WS_EX_RIGHTSCROLLBAR)))


но, есть жирное но, почему то WS_EX_RIGHTSCROLLBAR или WS_EX_LEFTSCROLLBAR никогда не отлавливается. В том же spy++ в свойствах элемента вижу WS_EX_RIGHTSCROLLBAR, у меня это не ловится. Естественно я задаюсь вопросом может я как то не так проверяю или не верно получаю эти свойства ?

Автор: Amp 20.11.2013, 11:52
Слушай, точно помню, что был какой-то опенсорсный аналог Spy++, но не могу вспомнить названия. В его исходники можно было бы посмотреть.

Автор: GremlinProg 21.11.2013, 06:48
Цитата(ecspertiza @  19.11.2013,  17:04 Найти цитируемый пост)
но, есть жирное но, почему то WS_EX_RIGHTSCROLLBAR или WS_EX_LEFTSCROLLBAR никогда не отлавливается. В том же spy++ в свойствах элемента вижу WS_EX_RIGHTSCROLLBAR, у меня это не ловится

Флага WS_EX_RIGHTSCROLLBAR не существует, поэтому и не отлавливиется. Этот флаг "логический", чисто для удобства восприятия кода, в противовес WS_EX_LEFTSCROLLBAR:
Код

#define WS_EX_LEFTSCROLLBAR     0x00004000L
#define WS_EX_RIGHTSCROLLBAR    0x00000000L

Цитата(ecspertiza @  19.11.2013,  17:04 Найти цитируемый пост)
или WS_EX_LEFTSCROLLBAR никогда не отлавливается

А вот это врятли. Другое дело, левый скроллбар у нас в основном не используется )

Добавлено через 4 минуты и 28 секунд
Впрочем, http://forum.vingrad.ru/index.php?showtopic=373553&view=findpost&p=2590248, Вам нужно ловить не WS_EX_(LEFT)[RIGHT]SCROLLBAR, а WS_(V)[H]SCROLL

Автор: ecspertiza 21.1.2014, 15:11
Уфф, давно сюда не заходил smile 

Цитата(GremlinProg @  21.11.2013,  06:48 Найти цитируемый пост)
Впрочем, как я уже говорил, Вам нужно ловить не WS_EX_(LEFT)[RIGHT]SCROLLBAR, а WS_(V)[H]SCROLL 



К сожалению этого мало, вот как пример стилей окна http://joxi.ru/kGPeUv3JTJD9ENPdLcU . Из того же spy++. У окна отсутствует WS_(V)[H]SCROLL, но есть WS_EX_RIGHTSCROLLBAR. Это окно Chrome.

Автор: GremlinProg 23.1.2014, 06:21
Цитата(ecspertiza @  21.1.2014,  17:11 Найти цитируемый пост)
К сожалению этого мало, вот как пример стилей окна http://joxi.ru/kGPeUv3JTJD9ENPdLcU . Из того же spy++. У окна отсутствует WS_(V)[H]SCROLL, но есть WS_EX_RIGHTSCROLLBAR. Это окно Chrome.

Если ни один http://forum.vingrad.ru/index.php?showtopic=373553&view=findpost&p=2590248 не определяет скролл, это еще не значит, что скролл не нарисован вручную. Мой Хром(32.0.1700.76), к примеру даже адресную строку генерирует без стандартного EDIT. Что ему какой-то элементарный скробблар  smile  Собственно, его скроллбар точно нарисован, т.к. уже отличается от стандартного визуально.

Добавлено через 3 минуты и 47 секунд
Наличие "вручную нарисованного скроллбара" программно Вы просто не определите...

Добавлено через 8 минут и 6 секунд
если только в частных случаях: чтение памяти процесса, определение каких-то индивидуальных структур для этого компонента, определение структур иерархии родительских компонент (если он не лежит в статической памяти), поиск в них методом чтения документации (что врят ли вообще документируется) ити "тыка".

Автор: GremlinProg 23.1.2014, 06:40
Цитата(ecspertiza @  21.1.2014,  17:11 Найти цитируемый пост)
У окна отсутствует WS_(V)[H]SCROLL, но есть WS_EX_RIGHTSCROLLBAR

WS_EX_RIGHTSCROLLBAR - антипод WS_EX_LEFTSCROLLBAR, он ни как не гарантирует наличия скроллбара, он гарантирует только то, что WS_EX_LEFTSCROLLBAR отключен, ничего более

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