Войти
  1. ВКонтакте
  2. Facebook
  1. »
  2. »
  3. »
  4. Прячем элементы управления
Скрыть панель справаПоказать панель справа

Прячем элементы управления

Мастер
  1. Офлайн
  2. Команда сайта.
  3. 885 сообщений
  4. Репутация: 6
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 1 отправлено 10:35, 09.04.2016
Прячем элементы управления


Тема создана по вопросу от пользователя minherc и здесь будет рассказано о том, как можно скрыть элементы управления в интерфейсе приложения. Повествование разбито на две части. Первая часть знакомит читателя с вариантами скрытия элементов управления, когда они доступны для редактирования обычными средствами. Во второй части рассматривается практическая сторона вопроса, когда элементы управления созданы средствами WinAPI и в ресурсах приложения недоступны.

ЧАСТЬ 1

Те из вас, кто занимается локализацией приложений, наверняка сталкивался с задачей скрытия элемента управления (кнопки, надписи и прочих) в интерфейсе приложения. Мы не будем останавливаться на вопросе "Зачем это нужно?" (причины могут быть разные). Лучше разберемся с тем, как это можно сделать.

Вариантов несколько и использование любого из них зависит от типа приложения, а также его сложности (в плане формирования интерфейса). Остановимся пока на приложениях, в которых интерфейсная часть находится в доступных для редактирования ресурсах ("RC_Data" в программах на языке Delphi и "Dialog" — языке C/C++).

Возможные варианты следующие:
1) Установить размеры желаемого элемента в ноль (и высоту, и ширину);

Рисунок 1.


2) Передвинуть элемент управления за пределы формы, т.е. изменить его координаты X и Y так, чтобы элемент находился за пределами видимой части диалогового окна.

Рисунок 2.


3) Закрыть элемент управления другим элементом. Кроме осей координат X и Y есть ещё ось Z. Она направлена от экрана к вам. Все элементы управления включая форму (диалог) как-бы нанизаны на эту ось и размещаются друг перед дружкой. Самая простая аналогия — это хорошо известная вам игрушка из детства пирамидка, в которой кольца надеваются на стержень.

Рисунок 3.


Так вот представьте, что стержень — это ось Z, кольца — это разные элементы управления, вся конструкция в целом (пирамидка) — это диалоговое окно. При размещении их в правильном порядке, если смотреть на диалог сверху (на экран), то все элементы будут видны. Если же немного изменить порядок, например, кольцо синего цвета разместить сверху кольца зеленого цвета, то вам будут видны только три кольца, кроме кольца зеленого цвета. Теперь применительно к нашему примеру диалога это будет выглядеть так:

Рисунок 4.


Как видите сейчас наверху z-порядка находится элемент "Button" с надписью "Copy". Его можно скрыть другим элементом "Button" с надписью "Exit". Для этого нужно всего лишь изменить порядок этих элементов и установить координаты кнопки с надписью "Exit" такие же, как у кнопки с надписью "Copy". Берем редактор ресурсов и работаем в режиме сценария формы (Resource Hacker, Restorator и др.). Здесь в текстовом виде перечислены элементы управления, которые использованы в диалоге, и их свойства (размеры, координаты, стили и т.д.). Порядок строк, в которых указаны элементы, определяет их порядок размещения на оси Z (Z-порядок). Таким образом в сценарии нужно переставить местами строки желаемых элементов управления.

Рисунок 5.


Теперь изменим координаты кнопки "Exit" на координаты кнопки "Copy". В итоге кнопка "Exit" закроет последнюю.

Рисунок 6.


Аналогично обстоят дела и в сценариях Delphi-форм (RC_Data). Здесь каждый элемент описывается между тегами "object" и "end". Чтобы переставить нужные элементы местами, вам нужно переставить местами соответствующие блоки текста и сохранить сделанные изменения. На следующем рисунке показаны элементы диалога, описанные в сценарии (нумерация элементов условная):

Рисунок 7.


4) Этот способ является вариацией предыдущего и заключается в добавлении на форму нового элемента управления, который будет закрывать собой нежелательный элемент. Правда для того, чтобы сделать это вручную, от вас требуются определенные знания в области программирования. Этот вопрос выходит за рамки данного руководства и, если вы хотите в нём разобраться, то займитесь его изучением самостоятельно. Но если вы не обладаете такими знаниями, то, например, редактор Radialix позволяет выполнить такую операцию для приложений на языке Delphi и C/C++. Щелкните правой кнопкой по форме, в пустом от элементов управления месте, и выберите в контекстном меню пункт "Элемент управления" и далее по списку:

Рисунок 8.


5) Скрыть элемент управления, используя свойство/стиль видимости. При создании приложения на этапе программирования каждый элемент управления наделяется свойствами. Некоторые из них вам хорошо знакомы — это ширина и высота, координаты X и Y, надпись и прочие. Среди них есть одно немаловажное свойство как "Видимость": на языке Delphi — "Visible", на языке C/C++ — "Visibility". Управляя всего лишь этим свойство можно оперативно включать или отключать видимость элементов управления и это очень широко используется в программах. Самый простой пример: в ознакомительных версиях программ после ввода данных регистрации пропадает кнопка "Купить" и появляются поля с лицензией.

В приложениях на языке Delphi для любого элемента управления, добавленного на форму, свойство "Visible" по умолчанию считается как "True", т.е. видимый, и в сценарии формы не упоминается. Если первоначальными условиями отображения формы на экране необходимо, чтобы элемент был не видим, то в сценарии для него записывается свойство "Visible" со значением "False". Затем, при работе программы, при наступлении заданных условий, данному элементу для свойства "Visible" устанавливается значение "True" и он становится видим. На основании этого мы теперь можем изначально в сценарии формы отключить видимость не нужного нам элемента управления, например кнопку "Buy". В редакторе ресурсов, в текстовом блоке выбранного элемента, добавляем строку Visible = False:

Рисунок 9.


Сохраняем сделанные изменения.

В приложениях на языке С/С++ все немного по-другому. Здесь любой элемент управления, добавленный на форму, по умолчанию считается невидимым. Чтобы сделать элемент видимым, для него задается свойство стилевого оформления окна WS_VISIBLE. Если вы посмотрите в сценарий формы любого приложения на языке C/C++, то почти у каждого элемента увидите стиль WS_VISIBLE. Таким образом, если необходимо скрыть неугодный нам элемент управления, то нужно просто в его свойствах удалить стиль WS_VISIBLE.

Рисунок 10.


Это можно сделать или напрямую в тексте сценария, или через редактор свойств элемента. Например, в Resource Hacker щёлкните по элементу правой кнопкой мышки и в контекстном меню выберите команду "Edit...". Откроется диалог редактирования свойств элемента:

Рисунок 11.


Не забудьте сохранить сделанные изменения.

Если вы работаете в редакторе Radialix, то перейдите на вкладку "Свойства" к необходимо элементу управления и найдите поле с заданными стилями. В режиме редактирования строки удалите стиль WS_VISIBLE...

Рисунок 12.


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

Рисунок 13.


На этом, пожалуй и все. Как видите здесь нет ничего сложного и по силу даже начинающим пользователям.




Но до сих мы вели речь о приложениях, чьи ресурсы были доступны для редактирования. А ведь многие из них могут быть написаны с использованием средств Windows API и не содержать ресурсов как таковых, кроме значка и манифеста. Могут быть приложения, в которых ресурс содержит шаблон формы, а элементы управления на неё уже добавляются при помощи Windows API. Также не забывайте про приложения, написанных с использованием кроссплатформенных виджетов Qt, wxWidget, FLTK и др. Как быть в этом случае? Варианты скрытия нежелательных элементов управления остались те же, только теперь процесс редактирования переходит непосредственно в код программы. Инструментальная часть — отладчики (OllyDbg, x64dbg, IDA и др.).

Но об этом мы поговорим уже в следующей части.

Продолжение следует...

Последний раз редактировал WYLEK 14:12, 15.02.2017

------------------------------------------
Кто ищет, тот всегда найдет!
Мастер
  1. Офлайн
  2. Команда сайта.
  3. 885 сообщений
  4. Репутация: 6
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 2 отправлено 10:39, 09.04.2016
Продолжение...

ЧАСТЬ 2

Основная задача — это найти в коде участок, который отвечает за создание или установку новых свойств нужного нам элемента управления. Методика выполнения поиска элементов неоднократно подымалась на страницах нашего форумах. Вы можете ознакомиться с ней, например, в следующих статьях "Проблемы локализации WinSpy++", "Как изменить размер ячеек в строке состояния", "Локализация FairStars Audio Converter Pro". Принцип все тот же, нового ничего нет.

Рассмотрим этот процесс с практической точки зрения ещё раз, на конкретном примере. В качестве пациента у нас будет небольшое приложение от Яндекс.Диск для создания скриншотов — Screenshots in Yandex.Disk v1.4.6.4977. Великолепная и удобная программка, в интерфейсе которой появилось желание убрать кнопку "Поделиться".

Рисунок 14.


Приложение написано на языке С/С++ и не богато на ресурсы. Точнее сказать, интересующего нас объекта там нет, как и всей формы главного окна. Поэтому, увы, скрыть кнопку обычными методами нам не под силу. Переходим к тяжелой артиллерии — отладчику. Но предварительно выясним, по каким признакам можно найти наш элемент управления.

Объекты поиска:

1. Идентификатор кнопки. В этом нам поможет утилита WinSpy++. Запускаем программу, наводим курсор мышки на значок прицела, зажимаем левую кнопку мышки, переносим прицел на нашу кнопку и отпускаем левую кнопку мышки. Готово. В главном окне WinSpy++ появятся основные свойства объекта исследования. Обратите внимание на значение поля "Control ID" — 8013шестнадцатеричном формате):

Рисунок 15.


Это уникальный идентификатор кнопки "Поделиться" в пределах данного приложения. По этому значению программа идентифицирует и обрабатывает все события, связанные с этим элементом управления. Но сначала, перед тем как элемент будет показан на экране, выполняется его инициализация: устанавливаются необходимые свойства и стили, назначается идентификатор, на который навешиваются соответствующие события. Затем элемент создается и только после этого он выводится на экран. Нас в отладчике будет интересовать именно та часть кода, где идет формирование элемента, и где мы можем установить нужные нам значения. Если вы зададите поиск значения 8013h, то скорее всего их будет найдено несколько. Поэтому необходимы дополнительные данные, по которым можно однозначно определить нужный участок кода. Этими данными могут служить размеры элемента, надпись на элементе, элементы расположенные рядом. Остановимся на надписи "Поделиться".

2. Идентификатор надписи на кнопке. Если вы занимались переводом строк приложения, то наверняка помните, что там была строка "Share" (Поделиться). А после её перевода и проверки локализованной версии приложения убедились, что она выводится на интересующем вас объекте. Каждому ресурсу приложения, на этапе его разработки, назначается уникальный идентификатор — номер, по которому приложение сможет их использовать. Когда программа работает, то для вывода того или иного ресурса на экран она обращается к соответствующему идентификатору. Так вот, посмотрите в редакторе ресурсов номер строки с надписью "Поделиться". Например, при переводе программы в редакторе Radialix, в редакторе строк он указан в первой колонке:

Рисунок 16.


Итак, идентификатор строки "Поделиться" — 4361 (в десятичном формате).

Так как кнопка "Поделиться" в интерфейсе приложения является статичной, т.е. во время работы приложения ни при каких условиях не изменяет своего состояния (не пропадает, не отключается, не перемещается), то имеет смысл сделать её невидимой, отключив стиль видимости (WS_VISIBLE). Проверим. Вернитесь к окну утилиты WinSpy++ и переключитесь на вкладку "Styles" (Стили). Здесь хорошо видно, что наш элемент использует стиль WS_VISIBLE:

Рисунок 17.


Щелкните по кнопочке [...] вверху справа над списком стилей. Откроется диалог редактора стилей.

Рисунок 18.


Отключите видимость (1), щелкнув по строке стиля WS_VISIBLE, и нажмите кнопку "Apply" (2). Теперь сверните и восстановите окно приложения (это необходимо для перерисовки окна, чтобы сделанные изменения вступили в силу). Кнопки с надписью "Поделиться" там уже не будет. Работает? :)

Обратите внимание на общее значение оконного стиля кнопки с установленным WS_VISIBLE: 50000000 (значение в шестнадцатеричном формате). С отключенным — 40000000. Здесь же в WinSpy++ можно узнать значение для каждого из стилей. У стиля WS_VISIBLE — это значение 10000000. Все значения стилей для любого из приложении Windows, независимо от языка программирования, являются константами и прописаны в спецификациях для разработчиков. Более подробно познакомиться со стилями можно в справочной системе MSDN. В коде программы элементам управления стиль оформления обычно передаётся напрямую уже общим значением. Если необходимо изменить стиль, что-то добавить или что-то удалить, то берете общее значение стиля и к нему или прибавляете, или отнимаете значение желаемого стиля, согласно списку.

Так вот, конкретно для нашей кнопки, во время её инициализации, оконный стиль задается общим значением 50000000. Чтобы сделать кнопку невидимой, нужно будет изменить это значение на 40000000 (50000000h — 10000000h = 40000000h).

Переходим к работе в отладчике. В этом примере я буду использовать отладчик x64dbg, а работать на виртуальной системе Windows XP SP3 (VMWare Workstation).

Настройки отладчика


Грузим исполняемый файл программы в отладчик. После останова на точке входа перед нами в окне "CPU" предстанет дизассемблированный листинг. Щелкаем в нём правой кнопкой и в контекстном меню выбираем команду поиска константы: Search for -> Current Module -> Constant:

Рисунок 21.


Откроется окошко ввода исходных данных, которые можно ввести в одном из четырех типов. Первая константа для поиска — идентификатор кнопки8013h. Значение в шестнадцатеричном формате, поэтому вводим его (или копируем и вставляем) в поле "Expression" (Выражение):

Рисунок 22.


Нажимаем "ОК" и получаем в окне "References" список адресов, где в инструкциях встречается константа 8013h:

Рисунок 23.


Сразу же поищем вторую константу — идентификатор строки "Поделиться" — 4361. Переключимся обратно в окно дизассемблера (CPU) и откроем окно поиска. Значение у нас в десятичном формате, поэтому вводим его в поле "Signed" (Знаковый):

Рисунок 24.


Получаем список адресов с константой 4361шестнадцатеричном формате 1109).

Рисунок 25.


В обоих случаях список найденных адресов небольшой и в первую очередь смотрим инструкции PUSH (запись в стек). Если вы сравните адреса 005E3831 (для константы 1109h) и 005E3863 (для константы 8013h) записи констант в стек, то увидите, что они находятся почти рядом. Это хороший знак. Посмотрим на код по этим адресам. Перед нами участок кода формирования кнопки с надписью "Поделиться":

Рисунок 26.


Ранее мы решили, что удобней и проще в нашем случае сделать кнопку невидимой, это удалить стиль видимости WS_VISIBLE = 10000000. Из общего значения стиля 50000000 отнимаем значение стиля видимости и получаем значение 40000000. Запишем это значение в инструкцию push 50000000 по адресу 005E386F. Для этого выделите в окне отладчика строку с адресом 005E386F и нажмите клавишу [Пробел]. Откроется окно редактирования ассемблерных инструкций. Измените в нём значение 0х50000000 на 0х40000000:

Рисунок 27.


Подтверждаем изменение инструкции, нажав "ОК".

Рисунок 28.


Теперь проверяем наши изменения. Выполните запуск программы в отладчике, нажав клавишу F9. Что вы видите? А кнопки-то нету! :D

Рисунок 29.


Точнее она есть, но не видна. Цель достигнута? Пожалуй, да. Осталось сохранить сделанные изменения в файл. Для этого переключитесь обратно в окно отладчика (запущенную под ним программу не закрывайте) и откройте окно патча, клавиши [Ctrl+P], или воспользуйтесь панелью инструментов.

Рисунок 30.


Нажмите "Patch File" (Внести изменения в файл), откроется стандартный диалог сохранения файла. Укажите имя файла, например "YandexDiskScreenshotEditor1.exe", и нажмите "Сохранить". Готово. Проверьте полученный файл в работе.

На этом, в принципе, можно было бы завершить наше повествование. Но можно пойти немного дальше. Кнопку мы спрятали, но теперь кнопка "Сохранить" неудачно "повисла" на панели, как говориться: "Ни к селу, ни к городу!". Было бы здорово разместить её в крайнем правом положении на месте скрытой кнопки "Поделиться". Сделать это можно очень просто: поменять кнопки местами!

Как узнать идентификатор кнопки и идентификатор надписи на ней, вы уже знаете. Воспользовавшись утилитой WinSpy++, получим ID кнопки "Сохранить"E103h. А идентификатор самой надписи "Сохранить" узнаем из редактора ресурсов — 4360 (1108h). Возвращаемся в отладчик и задаем поиск этих констант. Они будут найдены чуть выше того места, где мы только что выполняли изменение инструкции для кнопки "Поделиться".

Рисунок 31.


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

Исходные данные:
{кнопка "Сохранить"}
ID надписи — 005E37A5 | push 1108
ID кнопки — 005E37D1 | push E103

{кнопка "Поделиться"}
ID надписи — 005E3831 | push 1109
ID кнопки — 005E3863 | push 8013

Меняем местами ID:
{кнопка "Поделиться"}
ID надписи — 005E37A5 | push 1109
ID кнопки — 005E37D1 | push 8013

{кнопка "Сохранить"}
ID надписи — 005E3831 | push 1108
ID кнопки — 005E3863 | push E103

Таким образом, теперь у нас будет сначала формироваться кнопка "Поделиться", а потом кнопка "Сохранить". Переходим в отладчик и по адресу 005E37A5 меняем значение 1108h на 1109h. Затем по адресу 005E37D1 меняем значение E103h на 8013h. Теперь это будет кнопка "Поделиться", которую нужно скрыть, потому по адресу 005E37DD изменяем значения стиля 50000000 на 40000000. Получится так:

Рисунок 32.


Опускаемся ниже. По адресу 005E3831 меняем значение 1109h на 1108h. Затем по адресу 005E3863 меняем значение 8013h на E103h. Теперь это будет кнопка "Сохранить". Так как она должна быть видимой, то по адресу 005E386F восстанавливаем инструкцию со значение установки стиля (команда контекстного меню "Restore selection"). Получится вот так:

Рисунок 33.


Теперь сохраните сделанные изменения в файл (функция "Patch File").
Список изменений (патч):

Рисунок 34.


Запустите модифицированный файл программы и проверьте его работу. Если вы нигде не ошиблись, то все будет великолепно работать так, как и было нами задумано:

Рисунок 35.


Вот теперь с такой компоновкой элементов управления использование программы станет более удобным. Не правда ли?





Это мы рассмотрели всего лишь один случай из тысячи. Причем, не самый сложный. И хотя во многих случаях решение может быть типичным, то в некоторых, особо сложных, нужен индивидуальных подход и всесторонний анализ. А бывает так, что нужно сделать наоборот: включить отображение элемента или включить заблокированную функцию. Как например в ознакомительной версии приложения CHM Editor. Функция есть, а в интерфейсе она отключена. Поэтому изложенные выше знания можно применять в более широком диапазоне. Но это тема уже другого разговора.

Последний раз редактировал WYLEK 14:25, 15.02.2017

------------------------------------------
Кто ищет, тот всегда найдет!
Мастер
  1. Офлайн
  2. Команда сайта.
  3. 885 сообщений
  4. Репутация: 6
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 3 отправлено 10:47, 09.04.2016
Неожиданное продолжение...

ЧАСТЬ 3

С момента поступления вопроса и пока готовился материал, произошло обновление приложения — вышла Screenshots in Yandex.Disk v1.4.7.5052. Интерфейс претерпел изменения, появились новые функции. Все бы ничего, но разработчики облегчили себе жизнь, а нам усложнили. Кнопки на нижней панели инструментов, в том числе и наша кнопка "Поделиться", для утилиты WinSpy++ стали недоступны.

Рисунок 36.


Если попытаться навести прицел на одну из трёх кнопок, то выделяется вся панель инструментов. Что же теперь делать? И можно ли вообще что-то сделать? Попробуем разобраться.

Начнём поиск от панели инструментов, на которой находятся наши кнопки. WinSpy++ даёт нам идентификатор панели инструментов — E80Ah.

Рисунок 37.


Также, для ориентировки в коде, посмотрим идентификаторы строк на кнопках. Это можно сделать с помощью редактора ресурсов.

Рисунок 38.


Загружаем программу в отладчик и задаем поиск константы E80Ah (идентификатор панели инструментов). Получим одну единственную ссылку по адресу 00600551.

Рисунок 39.


Попробуем ещё поискать константы идентификаторов строк. Но увы, их поиск ничего не дает. Что же, тогда переходим на адрес 00600551 и начинаем анализировать этот участок кода (по адресам 00600520 - 00600655).

Таблица 1. Подпрограмма создания нижней панели инструментов.


Очевидно, что здесь идет формирование нижней панели инструментов с элементами управления. По адресу 00600563 в стек записывается общее значение стиля панели управления — 5600114C (шестнадцатеричный формат). Далее идут обращения к различным подпрограммам и в какой-то из них создаются интересующие нас кнопки. Как можно в этом убедиться? Обратите внимание на условный переход по адресу 00600590 (JNE) и следующую за ним инструкцию безусловного перехода (JMP) по адресу 00600592, которая в свою очередь ведёт на конец подпрограммы. В зависимости от результатов сравнения по адресу 0060058E часть кода с адреса 00600597 по адрес 00600647 будет или выполнена, или пропущена. Так вот, замените инструкцию по адресу 00600590 пустыми инструкциями NOP (команда контекстного меню "Binary -> Fill with NOPs"). Это исключит переход по условию и отправит выполнение кода на адрес безусловного перехода, т.е. часть инструкций выполнена не будет.

Рисунок 40.


Теперь запустите программу под отладчиком (F9). Что вы видите? Панель инструментов пуста!

Рисунок 41.


Таким образом удостоверились, что мы на верном пути. Перезагрузите программу в отладчике (Restart - Ctrl+F2) и вернитесь на участок кода, который мы только что исключили из выполнения (между адресами 00600597 и 00600647). Зайдите в каждую подпрограмму, которые вызываются инструкцией CALL, и сделайте анализ кода на предмет чего-то необычного. Например, в данном случае подпрограммы, адреса которых начинаются на 4ххххх, не представляют интереса. А вот те что выше 5ххххх, требуют более тщательного изучения. Начнем с подпрограммы, которая вызывается по адресу 0060059E (см. таблицу 1). Выделите в отладчике строку с этим адресом и нажмите клавишу [Enter]. Мы окажемся на адресе 00600060, в начале кода подпрограммы. Что здесь необычного и сразу бросается в глаза? Например то, что участок кода между адресами 0060007E и 0060010D выполняется трижды (смотрите инструкцию сравнения по адресу 00600087), и при выполнении последнего весь этот код будет пропущен.

Рисунок 42.


Если заглянуть в подпрограмму, которая вызывается по адресу 006000A6, то можно увидеть там вызов функции загрузки изображения — LoadImageW. Сразу возникает подозрение, что здесь выполняется загрузка каких-то изображений. Участок кода выполняется трижды и кнопок у нас три, и на каждой из них размещается иконка. Можно легко проверить свои догадки. Сделаем обход участка кода с адреса 00600091 по адрес 00600112. Для этого изменим инструкцию условного перехода (JAE) по адресу 0060008B на инструкцию безусловного перехода JMP. Выделяем эту строку, нажимаем клавишу [Пробел] и редактируем инструкцию:

Рисунок 43.


После этого запускаем программу на выполнение (F9). Что мы видим теперь?

Рисунок 44.


Да, на кнопках нет изображений! Какой делаем вывод? В подпрограмме по адресу 00600060 выполняется инициализация изображений для трех наших кнопок. Делаем себе пометку об этом и идём дальше. Перезагружаем программу в отладчике и возвращаемся в код программы по адресу инициализации панели инструментов (00600520).

Вызов подпрограмм по адресам 006005A5, 006005BD и 006005D9 пропускаем (см. табл. 1) — там нет для нас ничего интересного. Смотрим вызов подпрограммы по адресу 006005E3. Заходим в неё (выделили строку и нажали [Enter]). Мы на адресе 005FFF20 — начало подпрограммы. Посмотрите внимательно код, чуть ниже есть участок похожий на тот, который мы рассмотрели в подпрограмме инициализации изображений. Здесь также часть кода выполняется трижды:

Рисунок 45.


Если сделать обход этого участка кода, то кнопок на панели инструментов быть не должно. Давайте проверим. Изменим инструкцию условного перехода (JAE) по адресу 005FFFD4 на инструкцию безусловного перехода (JMP).

Рисунок 46.


Запустим программу под отладчиком на выполнение (F9). Действительно — кнопок нет!

Рисунок 47.


Итак, что имеем. Мы нашли участок, который формирует в памяти структуры с данными кнопок. Причём, для создания каждой из них используется один и тот же код, с адреса 005FFFD6 по 00600011 (см. рим. 45). Если помните, в предыдущей версии каждая кнопка формировалась индивидуально. Здесь же нет никаких явных свойств кнопки, которые мы могли бы отредактировать напрямую. Это пока пустышки, которые в последствии наполняются необходимыми свойствами. Одно из них — идентификатор кнопки — задается сразу. Смотрите, по адресу 005FFFF8 записана инструкция "movzx ecx,word ptr ds:[eax+6CD23C]". Она выполняет перенос в регистр ECX содержимого ячейки памяти по адресу EAX+006CD23C. Размер данных — WORD (4 байта). При первом проходе содержимое регистра EAX равно нулю, соответственно в регистр ECX попадёт значение из адреса 006CD23C. При втором проходе EAX=10 (в шестнадцатеричном формате), соответственно адрес будет уже 10+006CD23C=006CD24C. При третьем (заключительном) проходе — 20+006CD23C=006CD25C. Пройдём в дамп программы по адресу 006CD23C и посмотрим, что там. Для этого щёлкните правой кнопкой по выделенной строке с этой инструкцией и в контекстном меню выберите команду "Follow in Dump -> Address: EAX+6CD23C":

Рисунок 48.


Переключимся в панель дампа. Мы находимся на адресе 006CD23C. Первые 16 байт представляют собой массив с идентификаторами ресурсов для кнопки "Копировать". Под каждое значение выделено 4 байта (WORD). Посмотрите на рисунок 49:

Рисунок 49.


Первые четыре байта 18800000, выделенные прямоугольником красного цвета, являются идентификатором кнопки. Порядок размещения байт обратный, поэтому в нормальном виде значение идентификатора будет 00008018h. Следующие четыре байта E8A40000 — это ID строки на кнопке. Переворачиваем байты и получаем значение 0000A4E8h. В десятичном формате — 42216. Под этим номером в строковых ресурсах находится строка "Копировать":

Рисунок 50.


Следующие четыре байта 66020000 — это идентификатор изображения на кнопке. Переворачиваем байты и получаем значение 00000266h. В десятичном формате — 614. Под этим номером в ресурсах программы мы найдём значок (иконку):

Рисунок 51.


И последние четыре байта 73020000 — это идентификатор изображения на кнопке для состояния отличного от нормального (активного, неактивного или отключенного). Переворачиваем байты и получаем значение 00000273h. В десятичном формате — 627. Под этим номером в ресурсах программы вы найдёте соответствующий значок.

Аналогичные массивы идентификаторов также имеются для кнопки "Сохранить" (по адресу 006CD24C в дампе) и для кнопки "Поделиться" (по адресу 006CD25C в дампе).

Рисунок 52.


Итак, мы разобрались с идентификаторами и увидели, что для создания кнопок "Копировать", "Сохранить" и "Поделиться" используется используется один и тот же участок кода (см. рис. 45). Если вы продолжите анализ кода создания нижней панели инструментов далее, то увидите, что по адресу 00600614 выполняется вызов подпрограммы добавления строк на наши кнопки, а по адресу 0060061C создаются инструменты управления масштабом изображения. Теперь нужно подумать, как можно убрать из интерфейса кнопку "Поделиться".

Если вы были внимательны, то могли не заметить, что при добавлении значков (по адресу 0060059E, см. таблицу 1), создании кнопок (по адресу 006005E3, см. таблицу 1) и добавлении строк на кнопки (по адресу 00600614, см. таблицу 1), в указанных подпрограммах есть участки, которые выполняются трижды, соответственно количеству кнопок на панели инструментов. За это отвечает инструкция вида "cmp dword ptr ss:[ebp-8],3" по адресу 00600087 (для значков):

Рисунок 53.


Для создания кнопок инструкция вида "cmp dword ptr ss:[ebp-54],3" по адресу 005FFFD0:

Рисунок 54.


И для добавления строк на кнопки инструкция вида "cmp dword ptr ss:[ebp-4],3" по адресу 006002CF:

Рисунок 55.


Также, массивы с идентификаторами ресурсов для кнопок размещаются таким образом, что сначала идет обращение к данным для кнопки "Копировать" (соответственно она будет создана первой), затем для кнопки "Сохранить" и наконец для кнопки "Поделиться" (см. рис. 52). Таким образом, если во всех трех подпрограммах в инструкции сравнения изменить константу 3 на 2, то кнопка "Поделиться" создана не будет. Давайте проверим. Перейдите на адрес 00600087, выделите строку с инструкцией и нажмите клавишу [Пробел]. Измените в инструкции 3 на 2:

Рисунок 56.


Аналогичные изменения в инструкции сравнения сделайте по адресу 005FFFD0 (см. рис. 54) и по адресу 006002CF (см. рис. 55). Теперь запустите программу под отладчиком (F9). Что видим? Комментарии здесь излишни:

Рисунок 57.


Наша цель достигнута. Не забудьте сохранить сделанные изменения в файл.

Последний раз редактировал WYLEK 14:37, 15.02.2017

------------------------------------------
Кто ищет, тот всегда найдет!
Мастер
  1. Офлайн
  2. Админ
  3. 1593 сообщений
  4. Репутация: 1
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 4 отправлено 11:23, 09.04.2016
Все доступно и разложено по полочкам

Но, это для тех, кого такое напрягает. Хотя поковыряться и набраться опыта никому не помешает biggrin
Охотник
  1. Офлайн
  2. Стажер
  3. 156 сообщений
  4. Репутация: 0
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 5 отправлено 15:22, 09.04.2016
Цитата Bulba ()
 2) Передвинуть элемент управления за пределы формы,

Немножко поправлю...
Не рекомендуется располагать элементы справа или снизу окна. Окна бывают масштабируемые. Изменяемого размера. При изменении размера окна, элементы расположенные справа или снизу могут стать видимыми. По этому лучше расположить их слева или сверху задав отрицательное значение положения, к примеру что бы не ошибиться -1000. smile

Цитата Leserg ()
Попробуем разобраться.

Может быть это веб элемент? А кнопки обычный HTML? По идее в строках нужно поискать сначала... Мысли вслух... :)

Хороший материал. Как всегда с удовольствием читаю твои статьи.
Мастер
  1. Офлайн
  2. Команда сайта.
  3. 885 сообщений
  4. Репутация: 6
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 6 отправлено 18:30, 09.04.2016
Цитата mishem ()
Не рекомендуется располагать элементы справа или снизу окна. Окна бывают масштабируемые.

Верное замечание. Спасибо! agree
Но если форма имеет фиксированные размеры, то можно и так, как описано в статье.  wink

Цитата Bulba ()
в принципе материал мог быть от моего лица...

wow2 Попробуйте тогда завершить статью (исследование) для новой версии программы (ЧАСТЬ 3).


------------------------------------------
Кто ищет, тот всегда найдет!
Мастер
  1. Офлайн
  2. Админ
  3. 1593 сообщений
  4. Репутация: 1
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 7 отправлено 18:57, 09.04.2016
Цитата Bulba ()
Почему набросились на меня вдвоем в теме где человек просил помощи по этому вопросу, не пойму.


Уважаемый Bulba! На нашем сайте все равны, и все могут ошибаться, как говориться - знает все только гений, или идиот biggrin
Чтобы вам нормально отвечали, надо не прятаться за личными данными невесть какими wacko
Если вам есть что предложить - добро пожаловать в команду agree мы рады толковым людям.
Сталкер
  1. Офлайн
  2. Знаток
  3. 90 сообщений
  4. Репутация: 1
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 8 отправлено 20:32, 09.04.2016
Цитата WYLEK ()
О пользователе Bulba:"...не прятаться за личными данными невесть какими


"Мы все носим маски, и приходит время, когда мы не можем снять их, не затронув собственной кожи."
Андре Бертье

Последний раз редактировал kurkoff1965 20:34, 09.04.2016

------------------------------------------
\"Мое дело подарок подарить, а ты уж придумывай, что с этой хренью делать...\"
Охотник
  1. Офлайн
  2. Стажер
  3. 156 сообщений
  4. Репутация: 0
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 9 отправлено 22:11, 09.04.2016
Цитата Bulba ()
mishemВы не верно указали цитату сославшись в ней на мой ник.
Извиняюсь конечно, но я не указывал ваш ник. Каким то странным образом сгенерирвался ваш ник а не Leserg. Я просто выделяю текст который нужно цетировать и внизу сообщения жму "Цитата". Естественно я не проверяю чье имя было вставлено. По этому извиняюсь что не проверил. Хотя можно было догадаться что это не умышлено. :)

Цитата Leserg ()
Но если форма имеет фиксированные размеры, то можно и так, как описано в статье
Совершенно верно. Я ж и указал именно на этот момент: 
Цитата
Окна бывают масштабируемые. Изменяемого размера.

:)

Добавлено (09.04.2016, 20:11:01)
---------------------------------------------
Хотя добавлю, сначала написал, после стер, решил че воду вилами размазывать... Но да ладно, не сочтите за нравоучение. :)
Фиксированные то они фиксированные, но одна и та же форма может применяться для различных окон, и размеры формы могут меняться программно (больше\меньше). Все это конечно полемика, автор должен прятать кнопки от предыдущих окон и т.д.. но как говорится и ружье раз в год стреляет. И ссука стреляет именно не в то время и в не нужном месте. Все конечно предвидеть сложно, но такие моменты нужно просто брать за привычку, не внизу\справа, а вверху\слева, как правило. И 100% что это ружье повесит еще какое то время на стенке. :)
А так, в общем, по большому счету нет особой разницы. Особенно если уверен что эта кнопка или форма больше нигде не отображается.

Последний раз редактировал mishem 22:13, 09.04.2016
Новичок
  1. Офлайн
  2. Знаток
  3. 52 сообщений
  4. Репутация: 2
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 10 отправлено 19:49, 10.04.2016
Спасибо!

Очень интересная статья.

С уважением, Николай.
Новичок
  1. Офлайн
  2. Участники
  3. 41 сообщений
  4. Репутация: 0
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 11 отправлено 21:30, 10.04.2016
Leserg, великолепно написано! СПАСИБО!!!
Мастер
  1. Офлайн
  2. Команда сайта.
  3. 885 сообщений
  4. Репутация: 6
  5. Сообщение
  6. Личные данные
Полезность: 0 | сообщение № 12 отправлено 00:43, 17.04.2016
Добавлена третья часть руководства.


------------------------------------------
Кто ищет, тот всегда найдет!
 
Перейти
Найти

Доступ закрыт.

  1. Вам запрещено отвечать в темах данного форума.

Последние темы

  1. TotalD
    Автор: druc Вчера, 14:57
  2. Debut Video Capture Pro 4.04 Rus
    Автор: dinis124 12:22, 13.07.2017
  3. Abelssoft HappyCard 2017 1.2.146...
    Автор: dinis124 12:18, 13.07.2017
  4. Athentech Perfectly Clear Workbench...
    Автор: Ashoka 07:45, 13.07.2017
  5. DFX Audio Enhancer 12 RUS
    Автор: AlexSergeev 16:25, 09.07.2017
  6. QT приложения и методы их модификации
    Автор: bellic 12:28, 07.07.2017

Изменения статуса

  1. профиль Вопрос задать в теме для новичков не получается и Админу... Сегодня, 14:57
  2. профиль Не вернусь 18:24, 16.07.2017
  3. профиль Лучше быть бедным чем дешёвым. 17:18, 04.04.2017
  4. профиль Новичок 16:30, 10.02.2017
  5. профиль Офлайн 05:14, 11.12.2016