RLT*_*RLT 6 macos cocoa core-graphics objective-c quartz-graphics
我已经开发了注射系统并且已经连接了一些石英API,以便在Mac OS X上为窗口创建一些很好的效果.例如,当用户在窗口中将颜色设置为红色时,它是红色光泽的红色.
但是,当我注入已经运行的应用程序时,由于窗口已经被绘制,我无法给出所需的效果.所以,我正在寻找石英/核心图形中的东西,这可以让我重绘整个窗口或一些技术,这可以让我发送一些事件/调用一些功能,这将使系统重新整个窗口.
我的意思是窗口上的每个东西都要再次绘制,这样我的钩子API就会执行,以便创建正确的效果,阴影和颜色.这里创建和绘制窗口的顺序非常重要.
我使用的技术类似于注入和设置,注入代码是C/C++代码.
有谁知道如何实现这一目标?
-[NSView setNeedsDisplayInRect:]并且-[NSView setNeedsDisplay:]是直接的等价物invalidateRect.
我不知道你在Quartz/CoreGraphics中需要它的意思.可可已经在使用它们进行绘画了.
如果你想调用一些魔术CGxxx()函数来重新绘制窗口,则无法完成.窗口的标题和框架由系统绘制,但对于内容,低级API无法知道应该在那里绘制什么.唯一知道如何绘制视图的人就是视图本身.(也许在窗口的后备存储中有一些缓存,但我不知道任何公共或未记录的API来访问它).
无论您发现什么,都必须基于要求NSWindow对象重新绘制其视图.如果您已经注入流程,则可能涉及以下步骤:
objc_msgSend函数)+[NSApplication sharedApplication]和-[NSApplication windows]查找NSWindow*对象指针contentView,display等等重绘如果你想要一种强制窗口使用比Cocoa更低级别的API重绘自己的方法,那么据我所知,这是不可能的.当调用其内容视图的drawRect:方法时,窗口会重绘自身.它将CGContextRef传递给窗口,然后该方法用于重绘窗口.CoreGraphics不负责重绘窗口.Cocoa使用CoreGraphics重绘窗口.
可以在drawRect:之外获得一个窗口的graphicscontext,然后在你想要的时候绘制它(例如,参见这里),但听起来你真正想做的就是拦截窗口普通绘图程序的结果和做一些你自己的东西在顶部.您可以通过切换窗口内容视图的类并覆盖drawRect来实现此目的.处理注入的辅助函数看起来像这样:
typedef void (^InjectedBlock)(CGContextRef, CGRect);
void InjectIntoView(NSView* view, InjectedBlock aBlock)
{
Class viewClass = [view class];
InjectedBlock injectedBlock = [aBlock copy];
void(^drawRect)(id, SEL, NSRect) = ^(id self, SEL _cmd, NSRect rect)
{
struct objc_super superId = { self, viewClass };
objc_msgSendSuper(superId, @selector(drawRect:), rect);
injectedBlock([[NSGraphicsContext currentContext] graphicsPort], CGRectFromNSRect(rect));
};
NSString* subclassName = [NSString stringWithFormat:"%s_injected", class_getName(viewClass)]
Class subclass objc_allocateClassPair(viewClass, [subclassName UTF8String], 0);
objc_registerClassPair(subclass);
Method overriddenMethod = class_getInstanceMethod([NSView class], @selector(drawRect:));
IMP imp = imp_implementationWithBlock(drawRect);
class_addMethod(subclass, @selector(drawRect:), imp, method_getTypeEncoding(overriddenMethod))
}
Run Code Online (Sandbox Code Playgroud)
编辑:
啊,你对整个窗口感兴趣.框架等也是NSView实例,但它们是您无法直接访问的NSView的私有子类.您可以通过调用display窗口强制它们重绘,但这可能会覆盖您对窗口所做的任何操作,因为它将使用这些类的现有绘制例程.
所以,你也可能要考虑混写的的drawRect:这些视图方法(在调用[[获取到NSGraphicsContext currentContext] graphicsPort]中的drawRect:会给你一个CGContextRef,你可以用石英API使用).您可以通过调用superview窗口的内容视图来获取帧视图.
请注意,窗口框架视图的排列没有记录,可能随系统更新而改变.
听起来像一个有趣的项目,无论如何!
| 归档时间: |
|
| 查看次数: |
6177 次 |
| 最近记录: |