This is really a two question post:
First, I'm having a bit of trouble figuring out exactly when the right time to do something is. I'm going to be initializing some view data, which happens to be dependent on the view having been "created" (meaning the handle, and everything else - like size - of the window are valid and can be shown at any time). Hence, I can't put this code in the initialize method. I see overrides like hookWindowCreate, but I really am not sure what this does. I see this calls and onAboutToCreate method, and I've tried putting my init code in both, but doing this causes a recursive loop that always blows the stack. So, either I'm doing something wrong, or this is definitely the wrong place to put that code. If I put the code in another (public) function, I can call it after I've shown the view for the first time and everything works perfectly. I'd like this code to be private, because it should never happen more than once, I just don't know the method to override, sadly. And second, I need to resize the window before it is shown as well (again, only the first time). This is because the window size is actually incorrect. If someone overrides defaultExtent, and gives ^##(640 @ 480) as the default, then this isn't really the size of the client viewport (border and title bar haven't been taken into account). In Win32/C++, I would need to do the following before the window is actually shown: // the window has already been created, and we're going to resize it int style = GetWindowLong(hwnd, GWL_STYLE); int exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); // the desired viewport size RECT size = { 0, 0, width - 1, height - 1 }; // resize the rectangle to encompass the title bar AdjustWindowRectEx(&size, style, false, exstyle); // TODO: resize window with new size rectangle This code is easy enough to port over, once I know where to put it exactly. It should happen after creation (of course, I need the handle), but before my first problem (the private code initialization). Bah, while I'm already posting, I might as well ask another question: how can I set a breakpoint? I love the debugger, and am using it easily from the Workspace, but if I've overridden an event method, I'd like to be able to break inside when it's triggered (like when I click a button and get inside the button code). It isn't immediately obvious how to do this, and I haven't found anything in the documentation showing me how, but I'm sure it's there. Any suggestions? Thanks! Jeff M. |
Jeff,
> First, I'm having a bit of trouble figuring out exactly when the right > time to do something is. I'm going to be initializing some view data, > which happens to be dependent on the view having been "created" > (meaning the handle, and everything else - like size - of the window > are valid and can be shown at any time). Hence, I can't put this code > in the initialize method. If you look in the Presenter class you will find methods that are called (using Dolphins event mechanism) at certain times in the process of opening a view. Included in those are... #onViewCreated #onViewAvailable #onViewOpened The method comments give an indication of the state of the view at the time the method is called so choose the appropriate one. I tend to use #onViewOpened because everything (Model, View and Presenter) is available and the View is just about to become visible. The #onViewAvailable method is probably better for some situations though. To use it you just override it in your new Shell subclass. For example, say you have added a Shell subclass called MyShell. To resize the View [1] you would add a method MyShell>>onViewAvailable super onViewAvailable. self view extent: 400 @ 400 Try to remember the supersend. It's not important in this case but if you override #onViewOpened method then it is, and if you forget (which you will) then your views don't work as they should. [1] You can also specify a ShellView's size when you create it in the ViewComposer - see the #preferredExtent aspect > Bah, while I'm already posting, I might as well ask another question: > how can I set a breakpoint? I love the debugger, and am using it easily > from the Workspace, but if I've overridden an event method, I'd like to > be able to break inside when it's triggered (like when I click a button > and get inside the button code). It isn't immediately obvious how to do > this, and I haven't found anything in the documentation showing me how, > but I'm sure it's there. The Walkback and Debugger are opened every time an incorrect expression is encountered so to insert a breakpoint you just insert some code that will fail. self aSelectorThatDoesNotExist. for example. However, most people use self halt to bring up the debugger. OK, so you will now be saying "there should be some way of inserting a breakpoint without having to edit code" :-) It's a fair comment, and some Smalltalk implementations have addressed it, but I don't consider it a real disadvantage - you get a lot of flexibility this way. Conditional breakpoints can be so much more, um, conditional ... (anArgument = 10 and: [ self hadSecondCupOfTea and: [ date today isNotFriday]]) ifTrue: [self halt] The only danger is putting breakpoints in some of the methods that are involved with lower level windows and event handling. As Smalltalk programming works by modifying a running image putting a breakpoint is a method that is involved in displaying the Debugger, for instance, would cause problems! -- Ian Use the Reply-To address to contact me (limited validity). Mail sent to the From address is ignored. |
In reply to this post by Jeff M.
Jeff
> int style = GetWindowLong(hwnd, GWL_STYLE); > int exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); Just a small meta-point: While it is certainly possible to program at the level of the raw Win-32 API in Dolphin, and indeed it is sometimes necessary to do so, you should usually be able to do normal windowy things without dropping to that level. By "normal" I mean the kinds of GUI elements that you see in the IDE. So, unless you /want/ to work at that level (in which case, btw, ST-MT[*] might suit you better) it's generally worth looking around to see how Dolphin's MVP framework expresses the concepts you are looking for. In this particular case, as Ian has already mentioned, you can set the #preferredExtent -- which itself is part of a moderately sophisticated mechanism through which which Views and LayoutManagers negotiate component sizes. -- chris [*] ST-MT is a different Smalltalk implementation. It follows a different philosophy wrt. the Win32 API -- the approach seems to be to make it as convenient as possible to use it "raw", but not to abstract away from it; whereas the Dolphin approach is more about using the Win32 stuff to /implement/ a properly-designed GUI framework.) |
In reply to this post by Jeff M.
Jeff,
Have you by any chance purchased a copy of Ted Bracht's book The Dolphin Companion? He has a great insert at the back of the book that explains, in table format, the sequence of events when Dolphin opens a window. It has been an indispensable reference for us here. The book is dated to version 4 of Dolphin, but that hasn't hindered its usefulness in any appreciable way. Cheers, Eric > -----Original Message----- > From: Jeff M. [mailto:[hidden email]] > Posted At: Friday, June 09, 2006 8:21 PM > Posted To: comp.lang.smalltalk.dolphin > Conversation: What's the proper time for view initialization? > Subject: What's the proper time for view initialization? > > This is really a two question post: > > First, I'm having a bit of trouble figuring out exactly when the right > time to do something is. I'm going to be initializing some view data, > which happens to be dependent on the view having been "created" > (meaning the handle, and everything else - like size - of the window > are valid and can be shown at any time). Hence, I can't put this code > in the initialize method. > > I see overrides like hookWindowCreate, but I really am not sure what > this does. I see this calls and onAboutToCreate method, and I've tried > putting my init code in both, but doing this causes a recursive loop > that always blows the stack. So, either I'm doing something wrong, or > this is definitely the wrong place to put that code. > > If I put the code in another (public) function, I can call it after > I've shown the view for the first time and everything works perfectly. > I'd like this code to be private, because it should never happen more > than once, I just don't know the method to override, sadly. > > And second, I need to resize the window before it is shown as well > (again, only the first time). This is because the window size is > actually incorrect. If someone overrides defaultExtent, and gives > ^##(640 @ 480) as the default, then this isn't really the size of the > client viewport (border and title bar haven't been taken into > In Win32/C++, I would need to do the following before the window is > actually shown: > > // the window has already been created, and we're going to resize it > int style = GetWindowLong(hwnd, GWL_STYLE); > int exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); > > // the desired viewport size > RECT size = { 0, 0, width - 1, height - 1 }; > > // resize the rectangle to encompass the title bar > AdjustWindowRectEx(&size, style, false, exstyle); > > // TODO: resize window with new size rectangle > > This code is easy enough to port over, once I know where to put it > exactly. It should happen after creation (of course, I need the > handle), but before my first problem (the private code > > Bah, while I'm already posting, I might as well ask another question: > how can I set a breakpoint? I love the debugger, and am using it easily > from the Workspace, but if I've overridden an event method, I'd like to > be able to break inside when it's triggered (like when I click a button > and get inside the button code). It isn't immediately obvious how to do > this, and I haven't found anything in the documentation showing me how, > but I'm sure it's there. > > Any suggestions? Thanks! > > Jeff M. |
Free forum by Nabble | Edit this page |