На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> MVS: помогите найти место вывода переменной, или какие функции вообще искать
    Привет всем!
    Есть известная опенсурсная софтина CrystalDiskMark, исходник можно скачать с оф. сайта https://crystalmark.info/redirect.php?produ...stalDiskMarkSrc
    Написан в Microsoft Visual Studio без единого комментария. Пока добился того, что исходник у меня на машине компилируется и затем работает. https://cloud.mail.ru/public/KG1n/6DVkZHDoB
    Мне нужно забрать результаты теста и передать бекэнду сайта.
    Неожиданно для себя не могу найти место, где переменная из переменной превращается в циферку... После всех вычислений должно же быть место где некая переменная с результатом уходит в отображение.
    Опыт в с++ околонулевой, в универе пробовал с++ builder и там через форму можно было найти объект гуя и отследить связанные с ним переменные. Тут какого-то конструктора гуя не видно вообще, где переменные уходят в printf или что-то подобное тоже не понятно...
    Помогите плз их найти.
      Цитата Berbraer @
      Неожиданно для себя не могу найти место, где переменная из переменной превращается в циферку... После всех вычислений должно же быть место где некая переменная с результатом уходит в отображение.

      Попробуй произвести поиск по всем исходникам строки "sprintf".
        Код напичкан CString::Format()-ами. Походу именно так переменные и "превращаются в циферки".
          Цитата ЫукпШ @
          Попробуй произвести поиск по всем исходникам строки "sprintf".

          sprintf и т.п. в исходнике отсутствует (кроме пары мест записи в лог), его я первым делом искал, а других способов вывода данных на экран в си я не знаю.


          В коде где-то есть переменные, в которые в бинарной форме попадают результаты расчётов скорости диска и потом они уже как-то выводятся в гуй. Вот мне нужно эти переменные с готовыми результатами найти и данные забрать.
          Самое логичное, это найти место вывода в гуй и там найти эти переменные со значениями, чтобы перехватить для своих нужд. Вот эти самые места вывода данных на экран я и не смог найти.

          Qraizer, за подсказку CString::Format() спасибо, попробую разобраться что это.
          Сообщение отредактировано: Berbraer -
            Цитата Qraizer @

            Вернулся к задаче после небольшого перерыва, нашёл, что вывод происходит через DDX_Control, нашёл ID индикаторов и сам диалог:

            ExpandedWrap disabled
              void CDiskMarkDlg::DoDataExchange(CDataExchange* pDX)
              {
                  CMainDialogFx::DoDataExchange(pDX);
               
                  DDX_Control(pDX, IDC_BUTTON_ALL, m_ButtonAll);
                  DDX_Control(pDX, IDC_BUTTON_TEST_0, m_ButtonTest0);
                  DDX_Control(pDX, IDC_BUTTON_TEST_1, m_ButtonTest1);
                  DDX_Control(pDX, IDC_BUTTON_TEST_2, m_ButtonTest2);
                  DDX_Control(pDX, IDC_BUTTON_TEST_3, m_ButtonTest3);
               
                  //вот тут
                  DDX_Control(pDX, IDC_TEST_READ_0, m_TestRead0);
                  DDX_Control(pDX, IDC_TEST_READ_1, m_TestRead1);
                  DDX_Control(pDX, IDC_TEST_READ_2, m_TestRead2);
                  DDX_Control(pDX, IDC_TEST_READ_3, m_TestRead3);
               
                  DDX_Control(pDX, IDC_TEST_WRITE_0, m_TestWrite0);
                  DDX_Control(pDX, IDC_TEST_WRITE_1, m_TestWrite1);
                  DDX_Control(pDX, IDC_TEST_WRITE_2, m_TestWrite2);
                  DDX_Control(pDX, IDC_TEST_WRITE_3, m_TestWrite3);
               
              #ifdef MIX_MODE
                  DDX_Control(pDX, IDC_TEST_MIX_0, m_TestMix0);
                  DDX_Control(pDX, IDC_TEST_MIX_1, m_TestMix1);
                  DDX_Control(pDX, IDC_TEST_MIX_2, m_TestMix2);
                  DDX_Control(pDX, IDC_TEST_MIX_3, m_TestMix3);
                  DDX_Control(pDX, IDC_COMBO_MIX, m_ComboMix);
              #endif
               
                  DDX_Control(pDX, IDC_COMMENT, m_Comment);
               
                  DDX_Control(pDX, IDC_COMBO_COUNT, m_ComboCount);
                  DDX_Control(pDX, IDC_COMBO_SIZE, m_ComboSize);
                  DDX_Control(pDX, IDC_COMBO_DRIVE, m_ComboDrive);
                  DDX_Control(pDX, IDC_COMBO_UNIT, m_ComboUnit);
               
                  DDX_Control(pDX, IDC_DEMO_SETTING, m_DemoSetting);
                  DDX_Control(pDX, IDC_READ_UNIT, m_ReadUnit);
                  DDX_Control(pDX, IDC_WRITE_UNIT, m_WriteUnit);
               
              #ifdef MIX_MODE
                  DDX_Control(pDX, IDC_MIX_UNIT, m_MixUnit);
              #endif
               
                  DDX_Text(pDX, IDC_COMBO_COUNT, m_ValueTestCount);
                  DDX_Text(pDX, IDC_COMBO_SIZE, m_ValueTestSize);
                  DDX_Text(pDX, IDC_COMBO_DRIVE, m_ValueTestDrive);
                  DDX_Text(pDX, IDC_COMBO_UNIT, m_ValueTestUnit);
                  DDX_CBIndex(pDX, IDC_COMBO_COUNT, m_IndexTestCount);
                  DDX_CBIndex(pDX, IDC_COMBO_SIZE, m_IndexTestSize);
                  DDX_CBIndex(pDX, IDC_COMBO_DRIVE, m_IndexTestDrive);
                  DDX_CBIndex(pDX, IDC_COMBO_UNIT, m_IndexTestUnit);
              #ifdef MIX_MODE
                  DDX_CBIndex(pDX, IDC_COMBO_MIX, m_IndexTestMix);
              #endif
              }


            С утра пытаюсь достать значение m_TestRead. Тестирую на флешке, параметры которой известны. Пытаюсь просто умножить m_TestRead на 2-100, чтобы увидеть изменение цифры на экране ну и понять, что я добрался до непосредственно значения, а не указателя и т.п.
            И нифига. Либо заворачивает компилятор, либо компилятор пропускает, но на экране вообще ничего не изменяется...
            Обычно вижу это:

            ExpandedWrap disabled
              DDX_Control(pDX, IDC_TEST_READ_0, (m_TestRead0*100));
               
              1>F:\!!CrystalDiskMark8_0_2Src\CrystalDiskMark\DiskMarkDlg.cpp(193,50): error C2678: бинарный "*": не найден оператор, принимающий левый операнд типа "CStaticFx" (или приемлемое преобразование отсутствует)
              1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\d2d1helper.h(1003,1): message : может быть "D2D1_MATRIX_3X2_F operator *(const D2D1_MATRIX_3X2_F &,const D2D1_MATRIX_3X2_F &)" (компилируется исходный файл DiskMarkDlg.cpp)
              1>F:\!!CrystalDiskMark8_0_2Src\CrystalDiskMark\DiskMarkDlg.cpp(193,50): message : при попытке сопоставить список аргументов "(CStaticFx, int)"
              1>F:\!!CrystalDiskMark8_0_2Src\CrystalDiskMark\DiskMarkDlg.cpp(193,51): error C2660: DDX_Control: функция не принимает 2 аргументов
              1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\atlmfc\include\afxdd_.h(71,13): message : см. объявление "DDX_Control" (компилируется исходный файл DiskMarkDlg.cpp)
              1>Сборка проекта "DiskMark.vcxproj" завершена с ошибкой.
               
               
              -------------------
               
               
              m_TestRead0 *= 10;
               
               
              1>F:\!!CrystalDiskMark8_0_2Src\CrystalDiskMark\DiskMarkDlg.cpp(192,14): error C2676: бинарный "*=": "CStaticFx" не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору
              1>Сборка проекта "DiskMark.vcxproj" завершена с ошибкой.


            Раскурил код, насколько позволяют мои два с половиной познания Си. m_TestRead определена классом CStaticFx, этот класс написан автором кода. Но в DDX_Control она передаётся в стандартный класс CWnd, причём, через указатель, насколько понимаю значение символа &.
            В итоге, совершенно не понятно, появляется ли тут непосредственно результат вычисления скорости диска, или это некая смычка между классами и всё?...
            Я в глубокой растерянности. Как записать значение в лог представляю, собственно, у автора лог ведётся стандартным спринтф емнип. Но как достать переменные, содержащие значения выводимые на экран, не могу разобраться, памагити! :wall:

            Вот основыные части кода:

            ExpandedWrap disabled
                  CStaticFx m_TestRead0;
                  CStaticFx m_TestRead1;
                  CStaticFx m_TestRead2;
                  CStaticFx m_TestRead3;
               
                  CStaticFx m_TestWrite0;
                  CStaticFx m_TestWrite1;
                  CStaticFx m_TestWrite2;
                  CStaticFx m_TestWrite3;
               
              //-----------------------------------------------------------------------------
               
              void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl);
               
              //-----------------------------------------------------------------------------
               
              void CDiskMarkDlg::DoDataExchange(CDataExchange* pDX)
              {
                  CMainDialogFx::DoDataExchange(pDX);
               
                  DDX_Control(pDX, IDC_BUTTON_ALL, m_ButtonAll);
                  DDX_Control(pDX, IDC_BUTTON_TEST_0, m_ButtonTest0);
                  DDX_Control(pDX, IDC_BUTTON_TEST_1, m_ButtonTest1);
                  DDX_Control(pDX, IDC_BUTTON_TEST_2, m_ButtonTest2);
                  DDX_Control(pDX, IDC_BUTTON_TEST_3, m_ButtonTest3);
                  //m_TestRead0 *= 2;
                  DDX_Control(pDX, IDC_TEST_READ_0, (m_TestRead0));
                  DDX_Control(pDX, IDC_TEST_READ_1, m_TestRead1);
                  DDX_Control(pDX, IDC_TEST_READ_2, m_TestRead2);
                  DDX_Control(pDX, IDC_TEST_READ_3, m_TestRead3);
               
                  DDX_Control(pDX, IDC_TEST_WRITE_0, m_TestWrite0);
                  DDX_Control(pDX, IDC_TEST_WRITE_1, m_TestWrite1);
                  DDX_Control(pDX, IDC_TEST_WRITE_2, m_TestWrite2);
                  DDX_Control(pDX, IDC_TEST_WRITE_3, m_TestWrite3);
               
              #ifdef MIX_MODE
                  DDX_Control(pDX, IDC_TEST_MIX_0, m_TestMix0);
                  DDX_Control(pDX, IDC_TEST_MIX_1, m_TestMix1);
                  DDX_Control(pDX, IDC_TEST_MIX_2, m_TestMix2);
                  DDX_Control(pDX, IDC_TEST_MIX_3, m_TestMix3);
                  DDX_Control(pDX, IDC_COMBO_MIX, m_ComboMix);
              #endif
               
                  DDX_Control(pDX, IDC_COMMENT, m_Comment);
               
                  DDX_Control(pDX, IDC_COMBO_COUNT, m_ComboCount);
                  DDX_Control(pDX, IDC_COMBO_SIZE, m_ComboSize);
                  DDX_Control(pDX, IDC_COMBO_DRIVE, m_ComboDrive);
                  DDX_Control(pDX, IDC_COMBO_UNIT, m_ComboUnit);
               
                  DDX_Control(pDX, IDC_DEMO_SETTING, m_DemoSetting);
                  DDX_Control(pDX, IDC_READ_UNIT, m_ReadUnit);
                  DDX_Control(pDX, IDC_WRITE_UNIT, m_WriteUnit);
               
              #ifdef MIX_MODE
                  DDX_Control(pDX, IDC_MIX_UNIT, m_MixUnit);
              #endif
               
                  DDX_Text(pDX, IDC_COMBO_COUNT, m_ValueTestCount);
                  DDX_Text(pDX, IDC_COMBO_SIZE, m_ValueTestSize);
                  DDX_Text(pDX, IDC_COMBO_DRIVE, m_ValueTestDrive);
                  DDX_Text(pDX, IDC_COMBO_UNIT, m_ValueTestUnit);
                  DDX_CBIndex(pDX, IDC_COMBO_COUNT, m_IndexTestCount);
                  DDX_CBIndex(pDX, IDC_COMBO_SIZE, m_IndexTestSize);
                  DDX_CBIndex(pDX, IDC_COMBO_DRIVE, m_IndexTestDrive);
                  DDX_CBIndex(pDX, IDC_COMBO_UNIT, m_IndexTestUnit);
              #ifdef MIX_MODE
                  DDX_CBIndex(pDX, IDC_COMBO_MIX, m_IndexTestMix);
              #endif
              }
               
              //------------------------------------------------------------
               
              class CStaticFx : public CStatic
              {
                  DECLARE_DYNAMIC(CStaticFx);
               
              public:
                  // Constructors
                  CStaticFx();
                  virtual ~CStaticFx();
               
                  // Control
                  BOOL InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC,
                      LPCWSTR imagePath, int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL bDarkMode);
                  void SetMargin(int top, int left, int bottom, int right, double zoomRatio);
                  CSize GetSize(void);
                  void SetDrawFrame(BOOL bDrawFrame);
                  void SetDrawFrameEx(BOOL bDrawFrame, COLORREF frameColor = RGB(128, 128, 128));
                  void SetGlassColor(COLORREF glassColor, BYTE glassAlpha);
                  void SetMeter(BOOL bMeter, double meterRatio);
                  void SetLabelUnit(CString label, CString unit);
               
                  // Font
                  void SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio = 1.0,
                       COLORREF textColor = RGB(0, 0, 0), LONG fontWeight = FW_NORMAL, BYTE fontRender = CLEARTYPE_NATURAL_QUALITY);
               
                  // ToolTip
                  void SetToolTipText(LPCTSTR pText);
                  void SetToolTipActivate(BOOL bActivate = TRUE);
                  void SetToolTipWindowText(LPCTSTR pText);
                  CString GetToolTipText();
               
                  // Mouse
                  void SetHandCursor(BOOL bHandCuror = TRUE);
               
              protected:
                  // Draw Control
                  virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
                  virtual void DrawControl(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, CBitmap& ctrlBitmap, CBitmap& bkBitmap, int no);
                  virtual void DrawString(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct);
               
                  // Image
                  BOOL LoadBitmap(LPCTSTR fileName);
                  BOOL LoadBitmap(HBITMAP hBitmap);
                  void SetBkReload(void);
                  BOOL SetBitmap(CBitmap& bitmap);
                  void LoadCtrlBk(CDC* drawDC);
               
                  // ToolTip
                  void InitToolTip();
                  virtual BOOL PreTranslateMessage(MSG* pMsg);
               
                  // Message Map
                  DECLARE_MESSAGE_MAP()
                  afx_msg BOOL OnEraseBkgnd(CDC* pDC);
                  afx_msg void OnMouseMove(UINT nFlags, CPoint point);
                  afx_msg void OnMouseHover(UINT nFlags, CPoint point);
                  afx_msg void OnMouseLeave();
                  afx_msg void OnKillfocus();
                  afx_msg void OnSetfocus();
                  afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
               
              protected:
                  // Control
                  int m_X;
                  int m_Y;
                  CSize m_CtrlSize;
                  CRect m_Margin;
                  int m_RenderMode;
                  BOOL m_bHighContrast;
                  BOOL m_bDarkMode;
                  BOOL m_bDrawFrame;
                  COLORREF m_FrameColor;
               
                  CString m_Label;
                  CString m_Unit;
               
                  // Glass
                  COLORREF m_GlassColor;
                  BYTE m_GlassAlpha;
               
                  // Meter
                  BOOL m_bMeter;
                  double m_MeterRatio;
               
                  // Image
                  CString m_ImagePath;
                  int m_ImageCount;
                  CDC* m_BkDC;
                  CBitmap m_BkBitmap;
                  BOOL m_bBkBitmapInit;
                  BOOL m_bBkLoad;
                  CBitmap m_CtrlBitmap;
                  CImage m_CtrlImage;
               
                  // Font
                  DWORD m_TextAlign;
                  CFont m_Font;
                  CFont m_FontToolTip;
                  COLORREF m_TextColor;
               
                  // ToolTip
                  CToolTipCtrl m_ToolTip;
                  CString m_ToolTipText;
               
                  // Mouse
                  BOOL m_bHover;
                  BOOL m_bFocas;
                  BOOL m_bTrackingNow;
                  BOOL m_bHandCursor;
              };
              Цитата Berbraer @
              Но как достать переменные, содержащие значения выводимые на экран, не могу разобраться, памагити! :wall:

              Надо исследовать подсудимую программу.
              я делаю так:
              1. Скачаем программу DebugView с сайта Микрософт:
              DebugView
              2. Запустим прогу, увидим окошко.
              3. Добавим модуль с таким текстом в твою программу (или спрячем модуль в библиотеку):
              ExpandedWrap disabled
                void Type_Debug_String(const TCHAR* pFmt,...)
                {
                 if(!pFmt) return;
                 va_list ap;        //Указатель на список параметров
                 va_start(ap,pFmt); //Настроились на список параметров
                 TCHAR sss[32768];
                 _vsntprintf_s(sss,ARRAYSIZE(sss),_TRUNCATE,pFmt,ap);
                 ::OutputDebugString(sss);
                 va_end(ap); //Завершаем работу с макрокомандами
                }

              4. Если в исходниках исследуемой программы захочется подсмотреть,
              как менются некие переменные (в разных точках программы в процессе работы)
              просто пишем вывод в стиле С:
              ExpandedWrap disabled
                // если i - это int i, d - это double d
                 Type_Debug_String(_T("i=%d i=0x%X d=%e"),i,i,d);

              В окошке DebugView увидим выводимые строчки.
              итп итд
              -----
              Что касается всего исследования - у тебя есть подсказка.
              Объекты-строки содержат операцию "Format".
              Именно посредством этой операции, возможно, численные значения преобразуются
              в строку для последующего вывода в контрол.
              Значит, надо искать среди этих объектов-строк -
              какой из них содержит интересующую переменную.
              Добравшись до этого объекта можно искать дальше всю логику и историю
              вычислений/изменений/преобразований конкретной переменной.
              Сообщение отредактировано: ЫукпШ -
                Ок, поищу форматы. Но m_TestWrite и иже там не встречается точно. Придётся идти шагами...
                Но в строке DDX_Control(pDX, IDC_TEST_READ_0, m_TestRead0); переменная m_TestRead0 - строковая?
                А можно её из строки прям тут взад в бинарную преобразовать?
                Ну, кроме ручного метода вычитания 0x30 из символов, домножения на степень 10 и сложения :D
                  Цитата Berbraer @
                  Ок, поищу форматы. Но m_TestWrite и иже там не встречается точно.

                  Берем TotalCommander.
                  Начинаем поиск в директории с zip-ом исходников.
                  Указываем "все файлы", "ищем в архивах",
                  строка "m_TestWrite".
                  Обнаруживаем её тут:
                  user posted image
                  Смотрим файлы, и видим, что m_TestWrite - это объекты-статики:
                  ExpandedWrap disabled
                        CStaticFx m_TestWrite0;
                        CStaticFx m_TestWrite1;
                        CStaticFx m_TestWrite2;
                        CStaticFx m_TestWrite3;

                  T.е., по всей вероятности, это "станция конечная" для всех переменных.
                  Значение как-то добывается, считается. Далее преобразуется в строку,
                  а потом для отображения выводится в статик.
                  Переменную надо нежно брать за хобот в момент перед преобразованием
                  в строку. Именно в этой точке имеется готовое к выводу число.
                  Сообщение отредактировано: ЫукпШ -
                    Berbraer, почему бы тебе просто не сказать, какого результата ото всех своих усилий тебе хочется достичь?
                      M
                      Тема перенесена из C/C++ => C/C++: Общие вопросы
                      Сообщение на автоудалении
                        ЫукпШ, слухай, ну я не настолько тупенький чтобы не разобраться как искать по проекту в студии :) Просто сишные передачи указателей немного ломают мозг с непривычки + непонимание, какая функция стандартная и известно что делает, какая - самописная автором.
                        Но не суть, нашёл.
                        Окончательное вычисление/форматирование результата происходит в функции
                        void CDiskMarkDlg::SetMeter(CStaticFx* control, double score, double latency, int blockSize, int unit)
                        И выводятся в m_TestRead через void CDiskMarkDlg::UpdateScore()

                        Соответственно, в SetMeter можно перехватывать doble результаты.

                        Вдруг кому пригодится.

                        Qraizer, я же написал - достать бинарную переменную, а далее передать ея в интернет. Сделал через запись результатов в файл. Из своего клиента я отслеживаю изменение файла, и новую запись странслирую на сайт. Т.к. тест даже самого быстрого диска занимает минуту минимум, такой способ обмена вполне приемлем. И универсален.
                        Сообщение отредактировано: Berbraer -
                        1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0373 ]   [ 15 queries used ]   [ Generated: 2.08.21, 00:03 GMT ]