When I maximise one of my mdi client windows. I am then stuck with it maximised, I need to be able to restore it to view the other windows.
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wc.lpfnWndProc = CWindowHandler::MsgRouter;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = childClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
hChild = CreateMDIWindow(childClassName, "Segments", WS_OVERLAPPEDWINDOW, m_winRect.left, m_winRect.top, m_winRect.right - m_winRect.left, m_winRect.bottom - m_winRect.top, CWindowHandler::GetInstance()->GetMDIClient(), m_hInstance, (LPARAM)this);
i fixed this by calling return DefMDIChildProc(m_Hwnd, msg, wParam, lParam); in the case WM_SIZE: of the wndprocs of the child window. god knows why but it worked.
I believe you're going to have to add the style MDIS_ALLCHILDSTYLES in order to get the window styles you want. From MSDN...
The style of the MDI child window. If the MDI client window is created
with the MDIS_ALLCHILDSTYLES window style, this parameter can be any
combination of the window styles listed in the Window Styles page.
Otherwise, this parameter is limited to one or more of the following
values.
Related
I have a working app that draws NSAttributedStrings into a custom view. The NSAttributedStrings can included embedded images. This works on versions of macOS prior to Mojave. The app can display the strings on screen, print them, and save them to image files.
This is apparently broken under Mojave. Weirdly, printing and saving to image files still works; but on-screen, the strings display only the text and not the embedded images. Proper space is left for the images, but that space is blank.
I've tested by building a small app that shows a window with an NSTextField (a label) and a custom view. It makes a single NSAttributedString with an embedded image. It applies that string to the attributedStringValue of the label, and also calls drawInRect: on the same string in the drawRect: method of the custom view. In the label, the string is displayed correctly, image and all. But in the custom view, only the text appears, and the space where the image should be is blank.
Anybody got a clue why this is happening on Mojave but not on earlier versions of macOS?
Here is the code that makes the string (and caches it, for re-use):
static NSMutableAttributedString* sgAttrString = nil;
/*
* Creates an attributed string the first time it's called,
* then returns that same string each time it's called.
*/
+ (NSAttributedString*)getAttributedString
{
if (sgAttrString == nil)
{
NSFont* font = [NSFont fontWithName:#"Helvetica" size:24.0];
NSDictionary *attrs = #{
NSFontAttributeName: font
};
sgAttrString = [[NSMutableAttributedString alloc] initWithString:#"Daisy: " attributes:attrs];
NSImage* daisy = [NSImage imageNamed:#"daisy.png"];
[daisy setSize:NSMakeSize(24,24)];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
// I'm aware that attachment.image is available only on macOS 10.11 and later.
// It's not an issue in my real project.
attachment.image = daisy;
NSMutableAttributedString* imageStr = [[NSMutableAttributedString alloc] init];
[imageStr setAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
[sgAttrString appendAttributedString:imageStr];
[sgAttrString appendAttributedString: [[NSAttributedString alloc] initWithString:#" !!" attributes:attrs]];
}
return sgAttrString;
}
Here is the code that applies the string to the NSTextField:
NSAttributedString* str = [Utilities getAttributedString];
self.label.attributedStringValue = str;
And here is the code that draws the string in a custom NSView:
NSAttributedString* str = [Utilities getAttributedString];
[str drawInRect:NSMakeRect(50,50, 300, 40)];
Again, this behavior seems to occur only in Mojave! Thanks in advance for any help.
NSOutlineView is a subclass of NSTableView. And currently, NSTableView supports two implementations.
Cell-based.
View-based.
To make OSX 10.8 Finder style side bar (with automatic gray Icon styling), need to use view-based table view with source-list highlight style.
With NIBs, this is typical job. Nothing hard. (see SidebarDemo) But I want to avoid any NIBs or Interface Builder. I want make the side bar purely programmatically.
In this case, I have big problem. AFAIK, there's no way to supply prototype view for specific cell. When I open .xib file, I see <tableColumn> is containing <prototypeCellViews>. And this specifies what view will be used for the column. I can't find how to set this programmatically using public API.
As a workaround, I tried to make cell manually using -[NSTableView makeViewWithIdentifier:owner:] and -[NSTableView viewAtColumn:row:makeIfNecessary:], but none of them returns view instance. I created a NSTableCellView, but it doesn't have image-view and text-field instances. And I also tried to set them, but the fields are marked as assign so the instances deallocated immediately. I tried to keep it by forcing retaining them, but it doesn't work. NSTableView doesn't manage them, so I am sure that table view don't like my implementation.
I believe there's a property to set this prototype-view for a column. But I can't find them. Where can I find the property and make system-default NSOutlineView with source-list style programmatically?
If you follow the example in SidebarDemo, they use a subclass of NSTableCellView for the detail rows. In order to emulate the InterfaceBuilder mojo, you can hook everything together in the constructor. The rest is the same as the demo (see outlineView:viewForTableColumn:item:).
#interface SCTableCellView : NSTableCellView
#end
#implementation SCTableCellView
- (id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
[self setAutoresizingMask:NSViewWidthSizable];
NSImageView* iv = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 6, 16, 16)];
NSTextField* tf = [[NSTextField alloc] initWithFrame:NSMakeRect(21, 6, 200, 14)];
NSButton* btn = [[NSButton alloc] initWithFrame:NSMakeRect(0, 3, 16, 16)];
[iv setImageScaling:NSImageScaleProportionallyUpOrDown];
[iv setImageAlignment:NSImageAlignCenter];
[tf setBordered:NO];
[tf setDrawsBackground:NO];
[[btn cell] setControlSize:NSSmallControlSize];
[[btn cell] setBezelStyle:NSInlineBezelStyle];
[[btn cell] setButtonType:NSMomentaryPushInButton];
[[btn cell] setFont:[NSFont boldSystemFontOfSize:10]];
[[btn cell] setAlignment:NSCenterTextAlignment];
[self setImageView:iv];
[self setTextField:tf];
[self addSubview:iv];
[self addSubview:tf];
[self addSubview:btn];
return self;
}
- (NSButton*)button {
return [[self subviews] objectAtIndex:2];
}
- (void)viewWillDraw {
[super viewWillDraw];
NSButton* btn = [self button];
...
Here's #jeberle's code re-written in Swift 4 (five years later!):
class ProgrammaticTableCellView: NSTableCellView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
self.autoresizingMask = .width
let iv: NSImageView = NSImageView(frame: NSMakeRect(0, 6, 16, 16))
let tf: NSTextField = NSTextField(frame: NSMakeRect(21, 6, 200, 14))
let btn: NSButton = NSButton(frame: NSMakeRect(0, 3, 16, 16))
iv.imageScaling = .scaleProportionallyUpOrDown
iv.imageAlignment = .alignCenter
tf.isBordered = false
tf.drawsBackground = false
btn.cell?.controlSize = .small
// btn.bezelStyle = .inline // Deprecated?
btn.cell?.isBezeled = true // Closest property I can find.
// btn.cell?.setButtonType(.momentaryPushIn) // Deprecated?
btn.setButtonType(.momentaryPushIn)
btn.cell?.font = NSFont.boldSystemFont(ofSize: 10)
btn.cell?.alignment = .center
self.imageView = iv
self.textField = tf
self.addSubview(iv)
self.addSubview(tf)
self.addSubview(btn)
}
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var button: NSButton {
get {
return self.subviews[2] as! NSButton
}
}
}
Edit: I found a link (that will inevitably rot away – it was last revised in 2011) to Apple's SidebarDemo that #jeberle based his code on.
In addition to #jeberle 's answer, I need to note something more.
The key to keep the text-field and image-view is adding them as subviews of the NSTableCellView.
Set NSTableView.rowSizeStyle to a proper value (non-Custom which is default value) to make the table-view layout them automatically. Otherwise, you have to layout them completely yourself.
Do not touch frame and autoresizing stuffs if you want to use predefined NSTableViewRowSizeStyle value. Otherwise, the layout might be broken.
You can adjust row-height by providing private func outlineView(outlineView: NSOutlineView, heightOfRowByItem item: AnyObject) -> CGFloat delegate method. Setting NSTableView.rowHeight is not a good idea because it needs NSTableView.rowSizeStyle set to Custom which will turn off cell text/image layout management provided by default.
You can reuse row/cell views by settings NSView.identifier property. (example)
Here's the code I am using to blur an image using BitmapData. The function is called on a Slider_changeHandler(event:Event):voidevent and the value of the slider is passed to the function as blurvalue.
The problem is the function works but seems to be cummalative (if that's the correct word!), that is, suppose I slide it to the maximum and after that try to reduce the blur by sliding it back towards the front the blur still keeps increasing. How do I make it to work so when I will slide it up blur increases and when I slide it back blur decreases and when slider is at 0, no blur is applied.
var blur:BlurFilter = new BlurFilter();
blur.blurX = blurvalue;
blur.blurY = blurvalue;
blur.quality = BitmapFilterQuality.MEDIUM;
bitmapdata.applyFilter(bitmapdata,new
Rectangle(0,0,bitmapdata.width,bitmapdata.height),new Point(0,0),
blur);
return bitmapdata;
how about returning a clone of the original bitmapData with the filter applied ?
e.g.
var result:BitmapData = bitmapdata.clone();
var blur:BlurFilter = new BlurFilter();
blur.blurX = blurvalue;
blur.blurY = blurvalue;
blur.quality = BitmapFilterQuality.MEDIUM;
result.applyFilter(result,new
Rectangle(0,0,bitmapdata.width,bitmapdata.height),new Point(0,0),blur);
return result;
Also, if you're using the BlurFilter, you might need a larger rectangle, depending on the amount of blur. For that, you can use the generateFilterRect() method to get correct sized rectangle for the filter.
If I were you, I'd take the BitmapData and put it in a Bitmap object, then add the filters:
var bitmap:Bitmap = new Bitmap(bitmapData);
var blur:BlurFilter = new BlurFilter();
blur.blurX = blurvalue;
blur.blurY = blurvalue;
blur.quality = BitmapFilterQuality.MEDIUM;
bitmap.filters = [blur];
By doing this (interchanging the filters array), you're not making the filters cumulative.
I am facing a strange problem with the combobox in Flex. In the following code :
public function rollCombo(cmb:ComboBox,value:String):void
{
if(value=='') return;
var i:int=0;
cmb.selectedIndex = 0;
var dp1:XMLListCollection = (XMLListCollection(cmb.dataProvider);
trace(value);
while(dp1[i]!=value && i<dp1.length)
cmb.selectedIndex = ++i;
cmb.validateNow();
cmb.validateDisplayList();
trace(cmb.selectedLabel);
}
in an example case, at the end of the execution of the function, i is 7, and
cmb.selectedLabel is "xyz"(according to the trace output), but the label displayed
in the combobox is a different one.
Also, this is rather unpredictable. It happens sometimes and not always.
The last selectedIndex is out of range, because you use pre-incrementation. Which means i becomes dp1.length before the test, and it's assigned to selectedIndex too. That might explain the weird behavior. You'll probably want to use post-incrementation.
Also. The only thing that gets executed in that while looks to be
cmb.selectedIndex = ++i;
I don't know if that's what you wanted, but you might need some "{}" there.
I've ran into a weird problem with getCharBoundaries, I could not figure out what coordinate space the coordinates returned from the function was in. What ever I tried I could not get it to match up with what I expected.
So I made a new project and and added simple code to highlight the last charater in a textfield, and all of a sudden it worked fine. I then tried to copy over the TextField that had been causing me problems, into the new project. And now the same weird offset appeared 50px on the x axis. Everything else was spot on.
So after some headscracthing comparing the two TextFields, I simply can not see a difference in their properties or transformation.
So I was hoping that someone might now what property might affect the coordinates returned by getCharBoundaries.
I am using Flash CS4.
I've just had exactly the same problem and thought I'd help out by offering what my findings are. With a help from this thread, I tried to find everything that wasn't 'default' about the textfield I was using. I found that when I had switched my TextFormatAlign (or 'align' in the IDE) and TextFieldAutoSize properties to 'LEFT' as opposed to 'CENTER', it solved the problem.
A little late in the game perhaps, but worth knowing for anyone running into the same problem. This was the only thread I could find that raised the right flag...
Well the getCharBoundaries returns the boundaries in the textfield coordinate system. Where the origin is topleft corner of the textfield.
getCharBoundaries does not take into consideration the scrolling. you need to check if there are scrollbars on its parent (textarea) and if so relocate. One quick way of doing it is using localtoglobal and globaltolocal. Use the first to translate from the textfield coordinate system to the application coordinate system and then use the second to translate from the app coordinate system to the coordinate system of the parent of the textfield which is the textarea. I'm fine tuning a my method to get char boundaries i will publish it today on my blog
http://flexbuzz.blogspot.com/
Works For Me(tm) (Flex Builder AS3 project):
[Embed(systemFont="Segoe UI", fontWeight="bold", fontName="emb",
mimeType="application/x-font")]
private var EmbeddedFont:Class;
public function ScratchAs3()
{
stage.scaleMode = 'noScale';
stage.align = 'tl';
var m:Matrix = new Matrix(.8, .1, -.1, 1.1, 26, 78);
var t:TextField = new TextField();
t.autoSize = 'left';
t.wordWrap = false;
t.embedFonts = true;
t.defaultTextFormat = new TextFormat("emb", 100, 0, true);
t.transform.matrix = m;
t.text = "TEST STRING.";
addChild(t);
var r:Rectangle = t.getCharBoundaries(8);
var tl:Point = m.transformPoint(r.topLeft);
var tr:Point = m.transformPoint(new Point(r.right, r.top));
var bl:Point = m.transformPoint(new Point(r.left, r.bottom));
var br:Point = m.transformPoint(r.bottomRight);
graphics.beginFill(0xFF, .6);
graphics.moveTo(tl.x, tl.y);
graphics.lineTo(tr.x, tr.y);
graphics.lineTo(br.x, br.y);
graphics.lineTo(bl.x, bl.y);
graphics.lineTo(tl.x, tl.y);
}
To literally answer your question, it returns the coordinates in the TextField's coordinate system, not it's parent, and it is affected by DisplayObject.transform.matrix, which is the backing for the .x, .y, .scaleX, .scaleY, .width, .height, and .rotation properties.
What ever it was the solution was simple to add a new TextField, never found out what property screwed everything up.
The first answer is correct in most cases. However if your field is parented to another movie clip it may still return the wrong y coordinate. try this code:
//if this doesn't work:
myTextFormat = new TextFormat();
myTextFormat.align = TextFormatAlign.LEFT;
myFieldsParent.myField.autoSize = TextFieldAutoSize.LEFT;
myFieldsParent.myField.setTextFormat( myTextFormat);
//try this:
var x = myFieldsParent.myField.getCharBoundaries(o).x;
var y = myFieldsParent.myField.getCharBoundaries(o).y;
var myPoint:Point = new Point(myField.getCharBoundaries(o).x,myField.getCharBoundaries(o).y);
var pt:Point = new Point(myFieldsParent.myField.getCharBoundaries(o).x, myFieldsParent.myField.getCharBoundaries(o).y);
pt = myFieldsParent.myField.localToGlobal(pt);
//pt is the variable containing the coordinates of the char in the stage's coordinate space. You may still need to offset it with a fixed value but it should be constant.
I didn't test this code as I have adapted this example from code that is embedded into my project so I apologize if I'm missing something...