Presentation on theme: "Working with Windows Brian Levantine. What exactly is a window? In a graphical windows-based application, a window is a rectangular area of the screen."— Presentation transcript:
What exactly is a window? In a graphical windows-based application, a window is a rectangular area of the screen where the application displays output and receives input from the user. A window shares the screen with other windows, including those from other applications. Only one window at a time can receive input from the user. The user can use the mouse, keyboard, or other input device to interact with this window and the application that owns it.
Window monikers In a IB program, a window can be identified in one of two ways. By its handle or its ID (if assigned). – Window handles are 32 bit (4 byte) identifiers unique throughout the system. – Window identifiers or IDs are 32 bit values usually assigned by a designer application like Visual Studio that can be used to identify a window relative to its parent window (usually a dialog).
Getting the right perspective The purpose of the IB code you write in a windows program is to provide support to some window (usually a dialog) that is being maintained by COSW on your behalf. As a result, all files including DLLs, bitmaps, etc. must be available for direct access by COSW. This includes remote CometAnywhere clients. Information passed from an IB program to a window is actually sent to COSW which then forwards the information to the appropriate window. Conversely, information passed from a window is actually received by COSW and then forwarded to your IB program.
Exchanging information with a window using Messages Information is passed to and received from a window via the Windows Messaging API. Associated windows agree upon what messages they will use, the meaning of each message, and the parameters associated with a message. There are hundreds of message numbers pre-defined by Windows to maintain consistency among applications. Each message has its own set of parameters intended to convey whatever information the designer intended. Not all windows support all messages. A window need only support the messages required to conform to its pre- defined behavior.
COS.SendMessage the Windows Workhorse A message is sent to a window using the COS.SendMessage subroutine, a pre-built subroutine contained in the WDL source file CosWin.Ibs (more on that later). A message can convey information to a window or can request information from a window. This is determined by the pre-defined message number. COS.SendMessage always returns a 10.0 value (cosFuncResult) that can indicate the success or failure of a message or it can return some other value associated with the message. In addition, COS.SendMessage can also return a string of up to 254 bytes in the coslParam$ string.
COS.SendMessage parameters The COS.SendMessage subroutine uses pre- defined IB variables to pass parameters. The variables are defined in the WDL include file CosWIn.Inc (more on that later). The pertinent variables are: – Window handle (cosCWnd$): This is the handle of the target window. – Message number (cosMessage): This is a pre-defined message number that the target window expects and knows how to process. – Parameter #1 (coswParam): This is a 10.0 numeric parameter associated with the message number. – Parameter #2 (coslParam): This is either a 10.0 numeric or a 254 byte string parameter (determined by the Flag parameter) associated with the message number. – Comet exclusive flag parameter (cosFlags$): This parameter determines if Parameter #2 is a numeric or string value. This is determined by the message number.
COS.SendMessage in action Setting the caption text of a dialog: Gosub COS.OutInit! Always perform before use cosCWnd$ = cosDlghDlg$! Handle to dialog coswParam$ = NullDWord$! Not used coslParam$ = My Caption ! String parameter cosMessage = WM.SETTEXT! Set window text message cosFlags$ = LPARAMCOPY$! Were sending a string Gosub COS.SendMessageEx! Lowest level version
Shock Treatment Most commonly used messages have been pre-built into subroutines contained in the WDL IB source file CosWin.Ibs. Setting the caption text of a dialog: cosCWnd$ = cosDlghDlg$! Handle to dialog cosCtlText$ = My Caption ! String parameter Gosub COS.SetWindowText! Pre-built subroutine Getting the caption text of a dialog: cosCWnd$ = cosDlghDlg$! Handle to dialog Gosub COS.GetWindowText! Pre-built subroutine Caption$ = cosCtlText$! Resulting string
Receiving events from a window The opposite of a sent message is a received message or event and will consist of the following fields: – Window handle (cosCWnd$) Handle of the target window receiving the message. – Message number (cosMessage) Message number received – Parameter #1 (coswParam) Numeric value associated with message number. – Parameter #2 (coslParam$) This can be a numeric or string value which is determined by the message number. Numeric values are converted using the IHexDec function on the 1 st 4 bytes of the string.
Managing message traffic Even though we may not support most of the messages generated by a window the messages are still being sent. To prevent Comet from having to process all of these messages (were talking thousands per second when a window is being manipulated) and to prevent a huge amount of traffic for a CometAnywhere session, a filtering mechanism has been designed into the framework. To receive messages from a window an application must tell that window what messages it would like to receive.
Message filters There are three basic types of filters: – A generic message filter which passes almost any windows message to the application. – A Command filter which passes only WM.COMMAND messages to the application. – A Notify filter which passes only WM.NOTIFY messages to the application. During dialog initialization a program must tell the dialog which messages it wishes to receive. This is done with the following subroutines: – COS.AppendMsgFilter adds to the generic message filter. This is most commonly used for processing scroll messages from a Scroll or Spin control. – COS.AppendCmdFilter adds to the command filter and is the most common filter in use. – COS.AppendNotifyFilter adds to the notify filter and is used mainly by the new Windows common controls like ListView and TreeView.
Receiving events with EventSub In a IB program that is using the new CometWin framework, events are received via the EventSub mechanism. EventSub processes all messages using a user-defined IB subroutine. This is the EventHandler routine. Message Information is received into two pre-defined variables: CW.Event$ and CW.Source$ – CW.Event$ contains information about the event including all message parameters except the target window identifier. – CW.Source$ contains information about the source of the event. This would contain information about the target window. Before use, information received by the EventHandler must first be parsed into variables that have been pre-defined by the framework. The routine that parses an incoming message is CW.ParseEvent and should always be called first from within the EventHandler subroutine. Once parsing is completed, the user may then begin processing the message in whatever way required by the program.
Common Messages WM.INITDIALOG – Received when a dialog has finished construction but has not yet been displayed. – Ideal time to modify dialog components. – Automatically handled by the framework WM.DESTROY – Received after the dialog has been destroyed. – Best time to exit EventSub – Automatically handled by the framework WM.COMMAND – Most common message. – Received from controls to convey events WM.NOTIFY – Next most common message when using Windows common controls like ListView and TreeView. – Passes more information to program.
WM.COMMAND WM.COMMAND messages are received from most controls (or a menu) in response to user initiated keyboard or mouse events. Command events are parsed into the following pre-defined IB variables. – cosCWnd$ Handle to the window receiving the message. – cosCommand The command identifier as defined by the control. – cosCtlId The ID of the control sending the message. – cosCtlCWnd$ The handle of the control sending the message
Some Common WM.COMMAND notifications BN.CLICKED is probably the most commonly used command. It is sent by Button, Text, and Picture control when a user mouse-clicks on a control. The prefix BN indicates that it is a button notification. EN.KILLFOCUS is received from a Edit control to indicate that the control has lost the input focus. The prefix EN indicates that it is a Edit notification. LBN.SELCHANGE is received from a ListBox when the currently selected item changes. The prefix LBN indicates that it is a ListBox notification.
WM.NOTIFY WM.NOTIFY messages are received from the newer (IE 4.0) common controls in response to user initiated keyboard or mouse events. WM.NOTIFY events are parsed into IB variables like a WM.COMMAND message. Because WM.NOTIFY messages can and usually do contain additional information, separate calls must be made into the framework to parse out the additional data. Which subroutine is called depends on the control the message is received from and the type of information being sent. For example: For a ListView control that we want to monitor the currently selected item we would call the IB subroutine CW.ListView.UnpackMin. This would extract the basic information about the item that sent the notification. – cosItemId is the item of the item selected. This is the equivalent of a row#. – cosSubItem is the sub-item selected. This is the equivalent of a column#. – cosItemState is the state (focused, highlighted, etc.) of the item.
Some Common WM.NOTIFY notifications NM.CLICK is sent when a user clicks on an item in a control. NM.DBLCLK is sent when a user double clicks on an item in a control. LVN.COLUMNCLICK is sent when a user clicks on a header item in a ListView control.