11/25/2024 9:23:36 PM
|
|
slxdeveloper.com Community Forums |
|
|
|
The Forums on slxdeveloper.com are now retired. The forum archive will remain available for the time being. Thank you for your participation on slxdeveloper.com!
Forum to discuss writing script in Architect plugins for SalesLogix & general SalesLogix customization topics (for Windows client only). View the code of conduct for posting guidelines.
|
|
|
|
Form position at runtime
Posted: 28 Apr 06 6:55 PM
|
benadryl and pregnancy dosage benadryl and pregnancy fiogf49gjkf0d I use a tablet pc with slx. I create an assistant for input a number and calculation, I dont use the tip of tablet. The form created is simililary as numeric pad. I want positioning this form on a particular position on the called form, i try to use a property Left and Top but is not working.
Have you a suggestion for release this ?
ps: my english is very poor... I hope that is explicit |
|
|
|
Re: Form position at runtime
Posted: 29 Apr 06 9:04 AM
|
buy naltrexone naltrexone buy online canada go fiogf49gjkf0d The default is CenterParent i.e. it centers the form under whatever parent form calls it. I believe this is the default behavior.
There's another topic in this forum that covers a solution to the problem but due to the wording of the topic you wouldn't think it applies: http://www.slxdeveloper.com/forum.aspx?forumid=2000&postid=434
You have to use MainViews to call your custom forms and only with MainViews can you set the Height, Width, Left and Top properties as well. For an example here's nice MainView calling code in the "System: Insert Opportunity" form from SalesLogix
---- Begin snip ---- Sub OpenEditOpportunityCompetitorView Dim objMainView, objDetail
Set objMainView = Application.MainViews.Add("System:Edit Opportunity Competitor", 0, False) 'DNL objMainView.Caption = Application.Translator.Localize("Edit Opportunity Competitor") objMainView.Height = 390 objMainView.Width = 515 objMainView.CaptionBarVisible = False objMainView.BorderStyle = 3 Set objDetail = objMainView.DetailsView ---- End Snip (truncated because the rest doesn't apply) ----
You'd want to add objMainView.Left and objMainView.Top properties to the call of your specific forms and there are a LOT of other methods and properties that apply to the IMainView object. The LAN Developer's reference has everything you'll need.
One MAJOR caveat. MainViews were introduced in 6.2 so if you're on 6.1 or earlier you'd need to upgrade to take advantage of them. The only other method is as Ryan described in the other article: Win32 API hacking. He's the only person I know of who has an example on the subject so if anyone would know how to do it, Ryan would have a clue. |
|
|
|
Re: Form position at runtime
Posted: 29 Apr 06 9:07 AM
|
cook county abortion clinic how does an abortion work fiogf49gjkf0d I left out vital code which is the objMainView.ShowModal call. MainViews house your form but can be shown or hidden at will instead of just shown with the design-time properties. If you're going this route, study the developer's manual and test. I tried playing with the BorderStyle = bsSizeable property and while the form is resizable it operates a little funky.
Good luck |
|
|
|
Re: Form position at runtime
Posted: 29 Apr 06 8:28 PM
|
fiogf49gjkf0d I tried with objmainview and is not a solution: is it impossible to drive a frame position, and when I show this screen the other screen reopen, is very bad. After reflexion, I use the control panel container. I put into this panel a buttons (1,2,3..C,enter, and predefined number) and calculate the position of this panel. When I show this panel, I enabled=false all controls of the forms (register state enabled properties controls before) and after input i restore the all state controls. It's very simply code and posting is really fast and very fluid ! and I parameter the pad entirely under slx, this product is very interesting. |
|
|
| |
|
Re: Form position at runtime
Posted: 30 Apr 06 5:38 AM
|
fiogf49gjkf0d Originally posted by Jean-Claude Del bono
I tried with objmainview and is not a solution: is it impossible to drive a frame position, and when I show this screen the other screen reopen, is very bad. After reflexion, I use the control panel container. I put into this panel a buttons (1,2,3..C,enter, and predefined number) and calculate the position of this panel. When I show this panel, I enabled=false all controls of the forms (register state enabled properties controls before) and after input i restore the all state controls. It's very simply code and posting is really fast and very fluid ! and I parameter the pad entirely under slx, this product is very interesting.
|
|
If I understand you correctly, you're developing an input form/panel/set of controls to use with a Tablet PC. These are buttons that when pressed will type out 0-9 and do some math using buttons instead of the keyboard. The form is called on top of an existing form used as a edit control of sorts (like what happens when you click the ... of a picklist) and when done pipes the input back to the calling control. In many ways it's like an InputBox() but instead of just an editbox on the form that users type in, buttons are pressed because tapping the screen is preferable for Tablets.
The current implementation is a hidden form that is known at design/runtime that appears "docked" to the existing form. The MainView implementation offers a little promise by allowing you to set the Left and Top properties but you're not getting the same effect as the current implementation. The problem is by making this it's own form, there is no easy way of passing back the input to the calling Form.Control.Text. You can either use Form1.Control.Text and always hardcode the calling form in but this does not scale if you wish to use this input form in other places. I use global variables to pass a control's Text property back and forth between forms which keeps me from manipulating each form individually.
Here are a couple of suggestions that may bring it closer to a desired affect: 1) Use a separate form with it's own editbox that you use to pass Control.Text back and forth. This gives you the ability to correct mistakes BEFORE posting them to the calling control. 2) OnKeyPress on the Form or the edit control will let people type while this form is open. You could use the values pressed to hit the buttons on the form, which behaves a little like Calc.exe. 3) Make this change to the code I posted previously: Set objMainView = Application.MainViews.Add("My Form", 1, true) objMainView.BorderStyle = 4 This changes the borderstyle to a ToolWindow which make the form look more appropriate to me. Change the 1 to 2 in the MainViews.Add call to change the windowstyle from MDIClient(1) to StayOnTop(2). Playing with the border or window styles will give you something that "feels" a little better but may not be 100%. 4) Play with using Show instead of ShowModal. (4's subitems) a) Show disables OK, Cancel, and Help of a typical Data Form but you should be using a Manage Form anyway. b) Show also passes control back to the originator immediately so if you were to say LockControls(), Show, UnLockControls() it would process the UnLock while the form was still open. c) Users also have to click the X to close your Form but you should be able to use OnCloseQuery to prevent the form from closing if data is invalid for instance. 5) You can emulate a picklist control by calculating the calling controls right and bottom pixel location then moving your form's top right to align. You would also set borderstyle = 3 (bsDialog) and call ShowModal after everything to block the application until your form is done processing. 6) You can have a child form appear "docked" to the parent form. a) Call 2 mainviews: a parent and the child or input form b) Calculate both forms new left and top property since both forms shown at the same time will have less screen real estate. You don't want one form overlapping the other which is most likely what you'd get by default. c) ShowModal for the parent form and Show for the child form. d) The windowstyle may need to be adjusted to allow for both forms to be used at once.
I don't think anything will be a true 100% representation of what you have but using a little tweaking you could make something that functions similarly but behaves in a really cool way. You could probably even embed tablet ink controls on a form but that would require distributing the activex control if there even is one. I know you can access it through COM so it should be available but getting it to work nicely might be a fun exercise. |
|
|
|
Re: Form position at runtime
Posted: 01 May 06 8:57 AM
|
fiogf49gjkf0d 'lo Jeremy
Thank you for comprehension for my problem, you included/understood what I wished to do. Your suggestions are relevant but the execution of the code is slow and requires reopen forms take many resources.
Two points are important: 1) Procedure of seizure for a simple control like a edit. 2) Procedure of seizure in a datagrid
In the forms, I created a panel named ‘Pad‘, all field as ‘Picture’ (for the look):
Input field (afficheur) 789 456 123 0, Enter
And other predefined number.
And also a checkbox: called 'Tip', allowing the user to determine the seizure in normal mode or with the tip
In the first case: control "edit"
General déclaration : ' gestion du Pad dim padsender ' enregistre l'appelant dim padEtatCalledForm() ' enregistre l'état des controls enabled
The field control edit to be seized called upon the event ' OnEntercontrol' this sub:
Sub affichage(Sender) ' si demande assistant if padtip.Checked = false then exit sub set padSender = sender ‘backup the edit controls 'bloque ecran appellant PadModal ' position coin haut gauche ' test bas d'écran if sender.top + sender.height + 3 + pad.Height > frmInsertOpportunity.Height then pad.Top = sender.top - 3 - pad.Height else pad.Top = sender.top + sender.height + 3 end if if sender.Left + pad.width > frmInsertOpportunity.Width then pad.Left = frmInsertOpportunity.Width - pad.Width else pad.Left = sender.left end if ' visible pad afficheur.Text = sender.text pad.Enabled = true afficheur.Enabled = true pad.Visible = true End Sub
This routine protects the fields from the appealing screen. For the Pad panel as well as the fields which it contains the Tag property is well informed in order to avoid blocking these fields like these clean characteristics. In addition the table 'padEtatCalledForm' makes it possible to store the state of the property ' Enabled' of all fields:
sub PadModal dim i redim padEtatCalledForm(FrmInsertOpportunity.ControlCount - 1) For i = 0 To FrmInsertOpportunity.ControlCount - 1 padEtatCalledForm(i) = frmInsertOpportunity.Controls(i).Enabled if frmInsertOpportunity.Controls(i).tag = "0" then frmInsertOpportunity.Controls(i).Enabled = false next end sub
This routine restores the state ‘enabled’ all fields:
sub PadRestore dim i For i = 0 To ubound(padEtatCalledForm) frmInsertOpportunity.Controls(i).Enabled = padEtatCalledForm(i) next end sub
This routine is started on the ' OnClick' of the buttons of panel and test the tag property:
sub PadCommand(sender) select case sender.tag case 9999955 : padentre case 9999933 if len(afficheur.Text)>0 then afficheur.Text = left(afficheur.Text,len(afficheur.Text)-1) case 9999922 : afficheur.Text = "" case 9999911 : afficheur.Text = afficheur.Text & ","
case 99999010 : afficheur.Text = "10":padentre case 99999012 : afficheur.Text = "12":padentre case 99999015 : afficheur.Text = "15":padentre case 99999020 : afficheur.Text = "20":padentre case 99999050 : afficheur.Text = "50":padentre
case 9 : afficheur.Text = afficheur.Text & "9" case 8 : afficheur.Text = afficheur.Text & "8" case 7 : afficheur.Text = afficheur.Text & "7" case 6 : afficheur.Text = afficheur.Text & "6" case 5 : afficheur.Text = afficheur.Text & "5" case 4 : afficheur.Text = afficheur.Text & "4" case 3 : afficheur.Text = afficheur.Text & "3" case 2 : afficheur.Text = afficheur.Text & "2" case 1 : afficheur.Text = afficheur.Text & "1" case 9999900 : afficheur.Text = afficheur.Text & "0"
'command case 999901
case else end select
end sub
This routine is used at the time of the validation of seizure of the control pad
Sub PadEntre pad.Visible = false 'restore l'écran appellant PadRestore 'affiche le champ saisi padsender.text = afficheur.Text end sub
In the second case: datagrid.
Example on the screen ' Products' of opportunity. I integrate same Pad in the forms In the declarations to add:
dim padX,PadY,PadPrimaryKeyValue,PadFieldName
Function grdProductsEditing(Sender, PrimaryKeyValue, FieldName, Value) ‘Added tests if fieldname = "DISCOUNT" or fieldname = "QUANTITY" then set padsender = sender PadPrimaryKeyValue = PrimaryKeyValue PadFieldName = FieldName if fieldname = "DISCOUNT" then affichage(value*100) else affichage(value) end if end if ‘ end added test strCurrentValue = Value PrdGridCommonOnEditingEvents FieldName, Value End Function
Sub affichage(valeur) ' si demande assistant if padtip.Checked = false then exit sub 'bloque ecran appellant PadModal ' position coin haut gauche ' test bas d'écran if padY + 20 + 3 + pad.Height > GrdProducts.Height then pad.Top = padY - 3 - pad.Height else pad.Top = padY + 20 + 3 end if if padX + pad.width > GrdProducts.Width then pad.Left = GrdProducts.Width - pad.Width else pad.Left = padx end if ' visible pad afficheur.Text = valeur pad.Enabled = true afficheur.Enabled = true pad.Visible = true End Sub
sub PadCommand(sender) select case sender.tag case 9999955 : padentre case 9999933 if len(afficheur.Text)>0 then afficheur.Text = left(afficheur.Text,len(afficheur.Text)-1) case 9999922 : afficheur.Text = "" case 9999911 : afficheur.Text = afficheur.Text & ","
case 99999010 : afficheur.Text = "10":padentre case 99999012 : afficheur.Text = "12":padentre case 99999015 : afficheur.Text = "15":padentre case 99999020 : afficheur.Text = "20":padentre case 99999050 : afficheur.Text = "50":padentre
case 9 : afficheur.Text = afficheur.Text & "9" case 8 : afficheur.Text = afficheur.Text & "8" case 7 : afficheur.Text = afficheur.Text & "7" case 6 : afficheur.Text = afficheur.Text & "6" case 5 : afficheur.Text = afficheur.Text & "5" case 4 : afficheur.Text = afficheur.Text & "4" case 3 : afficheur.Text = afficheur.Text & "3" case 2 : afficheur.Text = afficheur.Text & "2" case 1 : afficheur.Text = afficheur.Text & "1" case 9999900 : afficheur.Text = afficheur.Text & "0"
'command case 999901 case else end select end sub
Sub PadEntre dim PadVal pad.Visible = false if PadFieldName = "DISCOUNT" then PadVal = cdbl(afficheur.Text/100) else padval = cdbl(afficheur.Text) end if grdProductsEdited PadSender, PadPrimaryKeyValue, PadFieldName, padval ‘ Call the existing sub for update grid 'restore l'écran appellant PadRestore end sub
sub PadModal dim i redim padEtatCalledForm(FrmOppProducts.ControlCount - 1) For i = 0 To FrmOppProducts.ControlCount - 1 padEtatCalledForm(i) = FrmOppProducts.Controls(i).Enabled if FrmOppProducts.Controls(i).tag = "0" then FrmOppProducts.Controls(i).Enabled = false next end sub
sub PadRestore dim i For i = 0 To ubound(padEtatCalledForm) FrmOppProducts.Controls(i).Enabled = padEtatCalledForm(i) next end sub
This procedure store the co-ordinates of the click mouse, to position the panel ‘Pad’:
Sub grdProductsMouseDown(Sender, Button, X, Y) 'reserve the axis PadX = X padY = Y End Sub
This code is simple and effective and certainly to improve, it does not have any claim, if it is only to solve the simplified parameter setting of an assisted seizure. Thank you for your help and time that you granted to me.
Jean-Claude
|
|
|
|
Re: Form position at runtime
Posted: 01 May 06 6:06 PM
|
fiogf49gjkf0d I think I understand case 1) Edit control of a specific form case 2) Inline editing of a datagrid field
Do you have a screenshot you could email to me or host on a website? It's hard to understand what you have versus what you want without seeing it in action.
Just from your code alone I can see how much of a beast this is. For every form you wish to include this you have to copy/paste both your code and the pad itself. You also tweaked roughly the same code for both case #1 and case #2 when you could probably refactor the code into a class or script to reduce the redundancy. You could call like PadEntre(Grid) or PadEntre(Form) to distinguish between the two cases.
The cool thing about using MainViews is the Show and Hide functions. You could load your Pad mainview at the beginning of every form that uses it then call Show and Hide only when you want to do processing with your form. I haven't tested this but you could probably reposition the form before the next Show so you can move your form underneath each control that calls it. Using this method instead of trying to build and destroy the form multiple times per input is wasteful. I'm sure there's some compromise that can make it faster and a little easier to work with.
I have a similar need so I think if you give me a screenshot I could build a bundle that accomplishes roughly the same thing by using MainViews. If you like it, keep it. If not, it's something I can put on my resume. Since I don't have a tablet PC myself, the SDK will only let me do basic manipulation of the ink control. If this wasn't the case I'd be trying to embed the ink control on an Active Form and just use that. Its a COM object but am not sure if it's a pure ActiveX control or not. If that didn't work all I'd have to do is wait until SalesLogix version 7 which should hopefully give us the ability to call .NET code. I do know I can place the ink control on a .NET form rather easily so eventually I'd just go that route. I'd love the ability to handwrite something and have it translate the resulting text into SalesLogix controls but without a tablet I wouldn't get very far with the SDK. |
|
|
|
You can
subscribe to receive a daily forum digest in your
user profile. View the site code
of conduct for posting guidelines.
Forum RSS Feed - Subscribe to the forum RSS feed to keep on top of the latest forum activity!
|
|
|
|
|
|
|
|