Best core-graphics questions in October 2011

Force a window to redraw itself using Core Graphics?

7 votes

I have developed injection system and have hooked some quartz API's to create some nice effects with windows on Mac OS X. For example, when user sets a color to red in window.. it is red glossy red.

But, when I inject in application which is already running, I cannot give it desired effects as window is already painted. So, I am looking for something in quartz/core graphics which can allow me to redraw whole window or some technique which can allow me to send some event/call some function which will make system repaint whole window again.

I mean every thing on window is to be draw again so that my hooked API's will execute in order to create proper effects, shades and colors. Here order in which window gets created & painted is important.

I am using technique similar to inject&interpose and injection code is C/C++ code.

Does anyone have an idea how can I achieve this?

-[NSView setNeedsDisplayInRect:] and -[NSView setNeedsDisplay:] are the direct equivalents of invalidateRect.

I don't know what you mean by that you need it in Quartz/CoreGraphics. Cocoa is already using them for drawing.

If you want to call some magic CGxxx() function that will make the window painted again, it can't be done. The window's title and frame are painted by the system, but as for the content, there is no way for lower level APIs to know what should be painted there. The only one who knows how to draw a view is the view itself. (Maybe there is something cached in window's backing store, but I don't know any public or undocumented APIs to access it).

Whatever you find just has to based on asking the NSWindow object to redraw its views. If you're already injected into a process, it may involve the following steps:

  • locating obj-c runtime (you will need at least objc_msgSend function)
  • locating NSApplication class
  • using +[NSApplication sharedApplication] and -[NSApplication windows] to find NSWindow* object pointer
  • using contentView, display etc. to redraw