2014-01-06 7 views
0

Мне нужно повторно перерисовать окно, показывающее какую-то форму непрерывного анализа. Сейчас:Что лучше всего подходит для многократного аннулирования окна с помощью InvalidateRect?

1) Если я сделаю это в WM_PAINT после картины, я в основном убиваю живопись всех остальных, поэтому ее нельзя использовать.

2) Если я делаю это по таймеру, это отчасти отстает.

Так что лучший способ сделать это, чтобы окно часто перекрашивалось, но когда ОС занята обработкой некоторых данных или рисует другие приложения, она снижает скорость. Я всегда думал, что ОС должна позаботиться о распределении мощности процессора между процессами, оставив графику вторичной, чтобы гарантировать, что фактическая обработка имеет достаточно времени, но она не выглядит так на Windows, ни на Mac.

+1

Если вы измените данные за отображаемым им видом, 'InvalidateRect()' для отключения бит краски должен быть в порядке. Однако вам не нужно отменять какой-либо регион, кроме обновленного, поэтому вы можете принять дополнительную меру для этого. Но ** никогда ** 'InvalidateRect' после того, как вы закончите' WM_PAINT' (т. Е. После вашего «EndPaint» .Это безумие. Вместо этого отправляйте событие потока или пользовательское событие в свою очередь из вашего кода для вычисления данных и имеете * что * обработчик в вашем окне proc 'InvalidateRect' и * возможно *' UpdateWindow'. – WhozCraig

+0

Почему тэг [cocoa]? – IInspectable

+0

Ну, это более или менее то, что я делаю сейчас. Крайняя вещь с признанием недействительности в wm_paint я пробовал только для «fun», это действительно не имеет большого смысла. Хотя, если os будет хорошо распределять процессор, это будет идеально, чтобы получить максимальную частоту кадров без заполнения очереди запросами. –

ответ

1

Обычно вы создаете таймер и аннулируете окно при каждом тике. Если есть отставание, может случиться так, что частота обновления слишком высока, или обработка, выполняемая в методе рисования, слишком дорога.

Имейте в виду, что игры со сложными трехмерными сценами обычно достигают 60 кадров в секунду (и выше). Таким образом, возможны высокие обновления частоты кадров.

Обратите внимание, что под Windows событие WM_TIMER, как известно, несовместимо. Возможно, вам понадобится изучить другие таймеры с высоким разрешением, если вам нужно разрешение более 1 секунды.

На Mac вы можете создать NSTimer и позвонить по телефону setNeedsDisplay:YES на свой NSView. Что-то вроде этого:

// in your init... method 
NSTimer* repaintTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 
    target:self 
    selector:@selector(timerTickHandler:) 
    userInfo:nil 
    repeats:YES]; 

// ... 

-(void)timerTickHandler(NSTimer*)timer { 
    [self.view setNeedsDisplay:YES]; 
} 

NSTimer в какао вполне надежен, так что выше должна хорошо работать, даже для очень быстрых обновлений.

Если вам необходимо обновить с частотой кадров (например, 25 кадров в секунду), посмотрите на поддержку CVDisplayLink. Это действительно необходимо только для видеоприложений и тому подобного.

+0

Спасибо, вот что я хочу попробовать сейчас. Btw действительно 1 секунду разрешения? –

+1

Ну, 'WM_TIMER' проблематично, поскольку несколько событий могут быть объединены, поскольку они реализованы как флаг в' GetMessage() '. Если вам нужны точные таймеры, есть несколько вариантов. Посмотрите, например, на мультимедийные таймеры. Вы не указываете, какие структуры вы используете, но это сравнение http://msdn.microsoft.com/en-us/magazine/cc164015.aspx стоит прочитать. – gavinb

 Смежные вопросы

  • Нет связанных вопросов^_^