2016-03-18 9 views
1

Я написал визу. Studio диалоговое приложение для удаленного управления части оборудования, которое включает небольшой ЖК-графический дисплей, который нам нужно просмотреть из диалога. Редактор диалога V.Studio, похоже, не представляет собой законченное решение. Будучи программистом Windows по необходимости, а не с призывом, я сделал следующее:Графика GDI в диалоговом окне

  • Добавлен элемент управления редактирования в диалог.
  • При поступлении обновления LCD изображение, создать CClientDC на поле редактирования
  • вызовов GDI функции для установки значения пикселей

Это кажется bletcherous, но делает работу, когда приходит образ. Очевидно, не перерисовывает изображение при перерисовании диалога. Код сохраняет данные изображения для перерисовки, но нет радости, пытаясь найти место для вызова функции перерисовки изображения, когда диалог перерисовывается.

  • Добавление вызова redraw в качестве последнего оператора в диалоговом окне Функция OnPaint() создает изображение, но сразу же уничтожается при возврате OnPaint().
  • Тот же результат при отправке пользовательского WM_DRAWLCD_MESSAGE в OnPaint() - изображение создается, но уничтожается.
  • Рамка не вызывает вызов EndPaint(), поэтому не может перерисовать изображение.

Два вопроса:
1. Существует ли вообще-акцепторный способ достижения этой цели?
2. Если нет, то где код может вызвать вызов функции перерисовки при перерисовании диалога?

@zeromus: LCD Image Мой «тостер» подключен к диалоговому окну и общается довольно хорошо. Образцом для ЖК-дисплея является содержимое панели ЖК-дисплея, установленной на аппарате для использования пользователем. Когда я диагностирую дистанционно, это будет проще сделать, щелкнув элементы управления диалогового окна под изображением, чтобы выполнить операции управления/состояния и увидеть ответ, а не дублировать все функции машины другими способами. Вещи работают так, как ожидалось, пока диалог остается наверху. Когда диалог не остается сверху, вернув его сверху, он не восстанавливает изображение. Данные и код, создающие растровое изображение, не являются частью элемента управления CEdit. Таким образом, вопросы: (1) Есть ли одобренный мастером способ отображения и восстановления измененного растрового изображения в диалоговом приложении (в отличие от отображения статического изображения) и (2) Если нет, есть ли место в диалоговом коде для соединения в вызове моей функции рисования растрового изображения во время перерисовки диалога? Благодаря!

+1

Решение простое: Добавить 'объект CBitmap' в качестве члена в диалоговом классе. Всякий раз, когда данные поступают, обновляйте данные растрового изображения и вызывайте 'InvalidateRect' для запуска обновления. В обработчике «OnPaint» просто визуализируйте растровое изображение. Если вам нужен заполнитель в ресурсе диалога, используйте невидимый статический элемент управления. Поскольку вы все одержимы использованием мастера MFC, вам следует подумать о двух шагах назад: «1» Изучите Windows API и «2». Узнайте о макросах препроцессора MFC в глубину. Если вы пропустите любой шаг, MFC значительно затруднит программирование Windows. – IInspectable

ответ

0

Принимая во внимание, что я не использовал MFC с того дня, как был выпущен .net, стратегия, которую я предлагаю вам вернуться вовремя и скопировать, обычным способом сделать это в окнах будет поддержка CBitmap, содержащего содержимое ЖК-дисплея. Тогда просто нарисуйте его в OnPaint - прямо в диалоговом окне будет проще всего. В Windows вы должны сделать все свое рисование на OnPaint, но вы можете делать все, что хотите раньше времени, чтобы быть готовым. Ваше участие в элементе управления Edit не может ничего помочь.

Поскольку для этого требуются абсурдно загадочные шаги, чтобы рисовать вещи в окнах даже с MFC, я вставлю свой тестовый код. Это может оскорбить ветеранов MFC, но оно выполняет свою работу, дает или принимает такое же управление жизненным циклом объекта. Он может содержать тонкие ошибки, поскольку все так сложно, но он показывает принцип рисования растрового изображения. Также, если вы все-таки рисуете на фоне диалога, вы можете захотеть сделать это в событии «erasebackground», я не знаю.

//create bitmap with updated contents 
bmp = new CBitmap(); 
bmp->CreateCompatibleBitmap(this->GetDC(), 100,100); 
__int32* buf = (__int32*)malloc(100*100*4); 
int r=rand(),g=rand(),b=rand(),a=255; 
for(int y=0;y<100;y++) for(int x=0;x<100;x++) buf[y*100+x] = b|(g<<8)|(r<<16)|(a<<24); 
bmp->SetBitmapBits(100*100*4,buf); 
free(buf); 

//when painting 
CPaintDC dc(this); 
CDC bitmapDC; 
bitmapDC.CreateCompatibleDC(&dc); 
bitmapDC.SelectObject(bmp); 
dc.BitBlt(0,0,100,100,&bitmapDC,0,0,SRCCOPY); 
+0

Смешивание 'malloc' и' new' неудобно. Создание совместимого растрового изображения, а затем игнорирование битдепа - ошибка. Ошибка, связанная с выравниванием строки, также является ошибкой. Не рекомендуется использовать 'CPaintDC' в обработчике сообщения' WM_ERASEBKGND'. Существует очень мало полезной информации, скрытой между множеством неправильных. – IInspectable

+0

@IInpectable - это растровое изображение из 'CreateCompatibleBitmap', которое не может быть 32 бит для современных дисплеев? Правильное использование здесь должно быть «bmp-> CreateBitmap (100, 100, 1, 32, buf)», но если монитор не поддерживает 32 бита, то это та же проблема. –

+1

@BarmakShemirani: 'CreateCompatibleBitmap' возвращает растровое изображение, которое * совместимо * с предоставленным контекстом устройства. Это не то же самое, что растровое изображение * без устройства *. Правильное использование заключается в использовании совместимого растрового изображения и реализации кода с использованием запрошенной глубины бит. – IInspectable

0
Here's what's working for me: 

Add two member variables to the dialog class: 

    CImage m_lcdImage; 
    CStatic m_lcdStatic; 

In the init dialog callback: 

    m_lcdStatic.Create("Static", 
    WS_CHILD | WS_BORDER | WS_VISIBLE | SS_BITMAP | SS_CENTERIMAGE, 
    CRect(<rectangle coordinates>), this); 

    m_lcdImage.Create(<bitmap extent + color depth>); 
    m_lcdStatic.SetBitmap(HBITMAP(m_lcdImage)); 
    drawLCD(); 

Add member function drawLCD() called in init or when bitmap changes: 

{ 
    // 
    // app-specific m_lcdImage.SetPixel() calls 
    // to update the bitmap 
    // 

    m_lcdStatic.InvalidateRect(NULL); 
}