Nano Hash - криптовалюты, майнинг, программирование

Почему мой пользовательский элемент управления, производный от CStatic, не получает сообщение WM_SIZE?

В настоящее время я разрабатываю настраиваемый элемент управления, производный от класса CStatic MFC (проект Smart Device C ++). Я создал класс управления с помощью мастера классов VC ++ MFC, выбрав класс CStatic в качестве базового класса. Я использовал представление классов, чтобы добавить обработчик событий OnSize для моего класса управления (я выбрал сообщение WM_SIZE из списка сообщений), и новый метод OnSize был создан Visual Studio вместе с оператором ON_WM_SIZE () между BEGIN_MESSAGE_MAP (...) и END_MESSAGE_MAP (). Проблема в том, что мой элемент управления не получает WM_SIZE, поэтому метод OnSize никогда не вызывается - я использовал MoveWindow для изменения размера моего элемента управления - его размер изменяется, как я видел в диалоговом окне, но сообщение WM_SIZE никогда не отправляется. Когда я отправляю WM_SIZE через функцию SendMessage или PostMessage - обычно вызывается метод управления OnSize. Что я не так? Я читал документы MSDN об управлении CStatic, и нет информации о том, что сообщение WM_SIZE никогда не отправляется в окно статического управления.

Извините за мой плохой английский.


Ответы:


1

Для проекта Windows, основанного на диалоге, я протестировал то, что вы описываете. Я получаю сообщения WM_SIZE в пользовательском элементе управления после вызова MoveWindow. Можете ли вы опубликовать несколько фрагментов исходного кода, особенно для диалогового класса, в котором вы используете свой собственный статический элемент управления для своего теста?

Обновите после публикации кода

Вы запускали это в отладчике? Мне интересно, почему вы не получаете сразу же исключение при открытии диалога, потому что CThreatSelection :: OnSize запускается как одно из первых событий, даже до того, как дескриптор окна threatGrid.m_hWnd вашего элемента управления вообще существует. Поэтому вызов threatGrid.MoveWindow в событии диалогового окна OnSize должен вызывать исключение при открытии диалогового окна.

Я не уверен, чего вы пытаетесь достичь, но похоже, что вы хотите изменить размер своего настраиваемого Static в соответствии с размером диалогового окна, как только диалоговое окно откроется:

Для этого возможной альтернативой может быть: Удалите CThreatSelection::OnSize и вместо этого поместите в CThreatSelection::OnInitDialog:

CThreatSelection::OnInitDialog()
{
    CDialog::OnInitDialog();

    // ... perhaps other Init-Stuff...

    CRect rect;
    GetClientRect(&rect);

    threatGrid.MoveWindow(0,0, rect.Width(), rect.Height(), FALSE);

    return TRUE;
}

Здесь вы можете вызвать угрозуGrid.MoveWindow, потому что дескриптор окна threatGrid.m_hWnd уже создан в OnInitDialog.

16.03.2010
  • На самом деле это то, что я искал :) Большое спасибо, и да, это мой самый первый вопрос, поэтому я прошу прощения за свой фрагмент кода, который неуместен. Я новичок в программировании собственных интеллектуальных устройств - вернувшись с C # - я хотел изменить размер элемента управления в соответствии с изменением ориентации экрана - в C # лучше всего было бы переопределить обработчик событий OnResize - поэтому я подумал, что это похоже на структуру MFC. .. Но, как Вы писали выше, это не так. 16.03.2010
  • Хорошо, я переместил инициализацию размера cotrol в метод OnInitDialog, но все же элемент управления OnSize никогда не вызывается системой ... 17.03.2010
  • Майкл, вы разместили код (ThreatGrid.MoveWindow) ПОСЛЕ CDialog :: OnInitDialog ()? (Я отредактировал фрагмент кода в своем ответе, чтобы прояснить это.) Это важно, иначе у вас будет та же проблема, что и раньше: угрозаGrid.m_HWnd еще не инициализирована. Можете ли вы отладить свой код (или вывести сообщение, если отладка на вашем интеллектуальном устройстве затруднена) и взглянуть на значение threatGrid.m_HWnd? При вызове MoveWindow он не должен иметь значение NULL. 17.03.2010
  • Да, я сделал. Проблема не в MoveWindow - мой элемент управления расположен правильно - ваш намек позволил мне исправить этап инициализации, но ... Проблема в том, что ориентация экрана изменяется на Windows Mobile. Сообщение WM_SETTINGSCHANGE отправляется в главное окно - я получаю его и вызываю MoveWindow в моем настраиваемом элементе управления внутри этого обработчика сообщений - затем элемент управления позиционируется правильно, но каким-то образом сообщение WM_SIZE никогда не перехватывается обработчиком сообщения OnSize элемента управления ... 18.03.2010
  • Чтобы все было понятно, я опишу, что я делаю: 1) Создание производного класса CStatic 2) Добавление обработчиков сообщений OnPaint, OnSize 3) Редактирование ресурсов (визуальный редактор) - добавление статического элемента управления в ресурс диалогового окна, затем добавление переменной в этот элемент управления , выбрав мой собственный класс в качестве класса управления 4) Поместите инициализацию размера моего элемента управления после оператора CDialog :: OnInitDialog 5) Установите точку останова внутри обработчика OnSize моего класса настраиваемого элемента управления 6) Отладка 18.03.2010
  • Результаты: элемент управления позиционируется правильно после КАЖДОГО вызова MoveWindow моего настраиваемого объекта управления. Отладчик никогда не останавливается на одной-единственной точке останова внутри элемента управления OnSize - даже если я помещаю DebugOutputString с некоторым текстом, он никогда не вызывается ... 18.03.2010
  • Теперь я действительно понятия не имею. Вы описываете именно то, что я сделал (старый компилятор Visual C ++ 6 в Windows XP), и я получаю сообщения WM_SIZE всегда после MoveWindow. Я предполагал, что это может быть связано с Windows Mobile, но этот документ MSDN для Windows Mobile (msdn.microsoft.com/en-us/library/aa932458.aspx) прямо говорит: "MoveWindow sends WM_WINDOWPOSCHANGED, WM_MOVE, and WM_SIZE messages to the window." Я не знаю, что не так в вашем примере. 18.03.2010
  • У кого-то была такая же проблема. К сожалению, им нужны деньги, чтобы просмотреть ответ: experts-exchange.com / Программирование / Система / Windows__Программирование / 18.03.2010
  • Я использую MS Visual Studio 2008 и разрабатываю для смарт-устройства - Windows Mobile - может быть разница в реализации MFC. Ничего страшного - теперь я решил использовать Frame - View design - View - это не элемент управления, а окно без строки заголовка и т. Д., И, наконец, он ПОЛУЧАЕТ WM_SIZE ... 20.03.2010
  • У меня немного другая проблема. Я создал подкласс статического элемента управления (ресурс CTEXT dlg), и вызывается функция OnSize моего диалогового окна, но функция OnSize настраиваемого элемента управления не вызывается после того, как я делаю MoveWindow, хотя в обеих картах сообщений есть запись ON_WM_SIZE(). Есть одна хитрость: один и тот же исходный код скомпилирован для Desktop Windows и WinCE. CCustomCtrl :: OnSize вызывается в Windows 7, но не в CE. 07.12.2012

  • 2

    Ниже приведен заголовок моего окна на основе CDialog, созданного мастером MFC.

    #pragma once
    #include "threatgrid.h"
    #define COLUMN_COUNT 4
    // CThreatSelection dialog
    
    class CThreatSelection : public CDialog
    {
        DECLARE_DYNAMIC(CThreatSelection)
    
    public:
        CThreatSelection(CWnd* pParent = NULL);   // standard constructor
        virtual ~CThreatSelection();
    
    // Dialog Data
        enum { IDD = IDD_THSELECT };
    
    protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    
        DECLARE_MESSAGE_MAP()
    public:
        virtual BOOL OnInitDialog();
    private:
    
    public:
    
        // My custom cotrol field
        CThreatGrid threatGrid;
        afx_msg void OnSize(UINT nType, int cx, int cy);
    };

    Вот тело:

    // ThreatSelection.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "SpeedNotifyNative.h"
    #include "ThreatSelection.h"
    
    
    // CThreatSelection dialog
    
    IMPLEMENT_DYNAMIC(CThreatSelection, CDialog)
    
    CThreatSelection::CThreatSelection(CWnd* pParent /*=NULL*/)
        : CDialog(CThreatSelection::IDD, pParent)
        , threatGrid(theApp.imaging, 3)
    {
    
    }
    
    CThreatSelection::~CThreatSelection()
    {
    }
    
    void CThreatSelection::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
        DDX_Control(pDX, IDC_THGRID, threatGrid);
    }
    
    
    BEGIN_MESSAGE_MAP(CThreatSelection, CDialog) 
        ON_WM_SIZE()
    END_MESSAGE_MAP()
    
    
    // CThreatSelection message handlers
    
    BOOL CThreatSelection::OnInitDialog()
    {
        CDialog::OnInitDialog();
    
        // TODO:  Add extra initialization here
        return TRUE;  // return TRUE unless you set the focus to a control
        // EXCEPTION: OCX Property Pages should return FALSE
    }
    
    
    void CThreatSelection::OnSize(UINT nType, int cx, int cy)
    {
        threatGrid.MoveWindow(0,0, cx, cy, FALSE);
        //threatGrid.SizeChanged(cx,cy); I use it normally because no WM_SIZE is sent to threatGrid
        CDialog::OnSize(nType, cx, cy);
        // TODO: Add your message handler code here
    }

    ... И мой заголовок настраиваемого элемента управления:

    
    #pragma once
    #include "atltypes.h"
    #include "GridIcon.h"
    
    // CThreatGrid
    class ImagingSystem;
    class CThreatGrid : public CStatic
    {
        DECLARE_DYNAMIC(CThreatGrid)
    
    public:
        CThreatGrid(ImagingSystem* imaging, int cols);
        virtual ~CThreatGrid();
    
    protected:
        DECLARE_MESSAGE_MAP()
    
    private:
        // Obiekt podsystemu obrazowania
        ImagingSystem* imaging;
        // Ilość kolumn w siatce
        int columns;
        // Spacing elementów
        int spacing;
    public:
        // Informuje kontrolkę o zmianie rozmiaru - dotychczas nie udało mi się znaleźć rozwiązania dlaczego WM_SIZE nie ejst wysyłane
        void SizeChanged(int cx, int cy);
    private:
        // Aktualny rozmiar - śledzony niezależnie aby uniknąć niepotrzebnych przeładowań obrazków
        CSize currSize;
        // Lista ikon
        std::vector icons;
    public:
        afx_msg void OnSize(UINT nType, int cx, int cy);
    };

    ... и мое настраиваемое тело управления:

    
    // ThreatGrid.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "SpeedNotifyNative.h"
    #include "ThreatGrid.h"
    
    
    // CThreatGrid
    
    IMPLEMENT_DYNAMIC(CThreatGrid, CStatic)
    
    CThreatGrid::CThreatGrid(ImagingSystem* imaging, int cols)
    : imaging(imaging)
    , columns(cols)
    {
    
    }
    
    CThreatGrid::~CThreatGrid()
    {
    
    }
    
    
    BEGIN_MESSAGE_MAP(CThreatGrid, CStatic)
    
        ON_WM_SIZE()
    END_MESSAGE_MAP()
    
    
    // Informuje kontrolkę o zmianie rozmiaru - dotychczas nie udało mi się znaleźć rozwiązania dlaczego WM_SIZE nie ejst wysyłane
    void CThreatGrid::SizeChanged(int cx, int cy)
    {
       CSize nSize(cx,cy);
       if(nSize != currSize)
       {
           currSize = nSize;
           int wspc = (int)(0.015 * cx);
           int hspc = (int)(0.015 * cy);
           spacing = (wspc  0 )
            {
                int rows = (icons.size() + columns - 1) / columns;
                int width = (currSize.cx - spacing * (2 + columns - 1)) / columns;
                int height = (currSize.cy - spacing * (2 + rows - 1)) / rows;
                CSize size;
                if ( width Calculate(i / columns, i % columns, abspoint, size, spacing);
                }
            }
       }
    }
    
    void CThreatGrid::OnSize(UINT nType, int cx, int cy)
    {
        CStatic::OnSize(nType, cx, cy);
    
        // NEVER CALLED BY SYSTEM 
    }
    
    16.03.2010
  • Ах да, между прочим: вы должны поместить пояснения по вашему вопросу (например, этот фрагмент кода) в исходный пост с вопросом (отредактировав его). Stackoverflow не имеет структуры дискуссионного форума. Один вопрос и (возможно) много ответов всегда должны быть четко разделены. Но мне кажется, это простительно за ваш самый первый вопрос здесь;) 16.03.2010
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..