Моя первоначальная мысль заключалась в том, что это был просто вопрос поиска нужного поля, но на самом деле это заняло немного больше времени. Если вы посмотрите на Control в Reflector, вы увидите, что свойство Visible вызывает GetVisibleCore, который проверяет поле внутреннего состояния на соответствие значению 2 (которое оказывается константой STATE_VISIBLE).
Итак, чтобы узнать, виден ли элемент управления, нам нужно найти поле состояния и выполнить некоторые битовые манипуляции.
Если у вас есть адрес экземпляра, вы можете сделать следующее:
.shell -ci "!do <ADDRESS>" grep state (use findstr, if you don't have grep)
Вывод примерно такой
0:000> .shell -ci "!do 015892a4" grep state
03aeedcc 400112c 4c System.Int32 1 instance 17432589 state <=== HERE!
03aeedcc 400112d 50 System.Int32 1 instance 2060 state2
049ac32c 40011ef d0 ...lized.BitVector32 1 instance 01589374 state
03aeedcc 40011f0 ad4 System.Int32 1 static 1 stateScalingNeededOnLayout
03aeedcc 40011f1 ad8 System.Int32 1 static 2 stateValidating
03aeedcc 40011f2 adc System.Int32 1 static 4 stateProcessingMnemonic
03aeedcc 40011f3 ae0 System.Int32 1 static 8 stateScalingChild
03aeedcc 40011f4 ae4 System.Int32 1 static 16 stateParentChanged
Обратите внимание, что есть два поля состояния. Я не изучал, почему это так, но вам нужен System.Int32. В моем примере он имеет значение 17432589.
Код в GetState выглядит следующим образом
return ((this.state & flag) != 0);
так что все, что вам нужно сделать, это (17432589 & 2) != 0
, и вы получите видимое состояние конкретного экземпляра.
На самом деле, вам, возможно, придется пойти еще дальше. Если приведенное выше возвращает false, вам нужно найти родителя и повторить трюк. В моем простом примере с использованием формы не было необходимости.
person
Brian Rasmussen
schedule
26.10.2009