Beiträge von nDragan

    Zitat von wpsupport


    When the WPA action "open" is used (also possible in toolbar, replace "diaopen" with "open") the converter DLLs are examined and used.

    This screenshot of the filter list in a file open dialog was taken on Windows 7 - 64 bit

    Julian


    Hi... me again, after a long time.

    I am in the process of looking for a component to replace Word as a reporting tool, which means I have a lot of doc files with mergefields in them, and I'd like to keep using them as they are. The process is automated, which means I need to open these files programmatically, without any dialogs at all. What should I pass as a format string to .LoadFromFile() or to .wpaProcess()?

    After two weeks of emails between Julian and me, we have a solution on how to access other interfaces in WPTDynInt (like .memo, .SpellCtrl etc).

    It was Julian who found the VFP function GetInterface() (I'm ashamed - my last boss said I was among the top 100 VFP programmers in the world and I couldn't remember this function - there are only 445 of them).

    In short, the solution:

    somewhere in the code, best in .oTextDyn.Init

    Code
    ospell=GETINTERFACE(this.SpellCtrl, "iwpspell", "WPTDynInt.ocx")ospell.AddFromFile(FULLPATH("words.dct"))ospell.AddFromFile(FULLPATH("english.dct"))

    and that's it. Alternatively, the first line can be

    Code
    ospell2=GETINTERFACE(this.SpellCtrl, "{8A8763C7-D866-4D33-A6E9-FF17C008D57B}", "WPTDynInt.ocx")


    (Julian sent me the list of GUIDs)

    There are other things that can be done this way. Using GetInterface(), I can access other things, like .memo etc, as needed. :wink:

    Great!

    I was able to insert my own print dialog (with just a filtered printers list and the Print Pages optiongroup) and it now prints what and where I want.

    I had to remove the PrintPreview for obvious reasons - I can't intercept anything there, and it allows saving into plain .rtf file, which is a no-no in the app I'm making, but it's no big deal. The editor is already quite WYSIWYG, so print preview won't be missed.

    Now the only remaining thing is the registration of the dictionaries (from the other thread) and we'll be ready to deploy.

    Thanks!

    Zitat von wpsupport


    And, yes, "print" for print only, "PrintDialog" and "DiaPrint" show the print dialog. The ImagePack program shows a searchable table with "wap" commands.

    Solved the rest - now only for the printing. I have two conflicting requirements: to exclude certain printer drivers (like the Document Image Writer and any PDF writer) and yet to have some dialog to enable printing a page range.

    I can't have the standard dialog with those printers removed. I can hide them, but the code to do that is unreliable, slow and ugly. The other way around would be to have my own dialog with a filtered selection of printers (and yes, .SelectPrinter() method works fine), but I need a way to have a way to pass a page range.

    What's missing here is a wpaPrintPages wpa command. I can't use the .memo property, because it behaves just the same as the def parameter in the OnButton event, i.e. whichever of its properties I try to access, it errors with "not implemented", although my IntelliSense sees them all. Also tried to hook an event handler on it, doesn't fire. So I have no way to print a page range.

    I see two ways out of this - adding the wpa command (simpler, IMO, and more sure to work) or exposing the IWPMemo interface just the way the IWPDLLInt and IWPDLLIntEvents are exposed in the TLB. For some reason, those two are bolded in my object browser, and they list the PEMs (properties-events-methods, as called in Foxspeak) that I can use.

    Zitat von wpsupport

    Hi,

    >> What do you mean by "print a control"?

    I think I got my answer :-)

    That's why I wrote it :).
    Actually, "print a control" either makes no sense, or can mean any of
    - printing a screenshot of it
    - printing all of its properties
    - getting its value into something that'd print

    Since I'm the oddball here, I rather asked a stupid question than make a stupid assumption - what may it mean here :).

    Zitat von wpsupport

    In MS Access you can place text fields, images, labels and TextDynamic on your form (a virtual piece of paper) and with the upcoming release also TextDynamic will print into its bounding rectangle.

    VFP form is where I'm hosting the TD OCX, along with just a few of my buttons (I've taken over the open/save/new because I need to handle the files myself).

    So printing into its current form would be like a print preview?

    BTW, for the next version, if possible: ctrl+B, ctrl+U and ctrl+I could run the bold, underline and italic toggles, just like they do in other editors. There may be people who are used to that. I tried catching that in OnKeyUp (or something with a similar name), but the shift parameter kept coming as zero, no matter which of ctrl+alt+shift I had pressed.

    Having solved the rest of my problems, here's another one that popped up:

    Not all of the icons are self-explanatory. I've had my customer (who isn't the computer illiterate as the end users mostly are) complain about being unable to do a few things until I told him where to click. Then he asked whether there's some sort of end-user manual with explanations of all the buttons.

    I've searched the site and found only programmers' reference material, but no end user stuff. So... is there such a thing?

    Zitat von wpsupport

    Hi!

    Something else ...

    Normally you will use TextDynamic itself to print, but I now also made the OCX as such printable (it does not resize itself since there is no interface which controls this and stretching is of course impossible) - but on a standard MS Access Form this is a pretty nice feature. I don't know if this also works under Visual FoxPro - do you know if it also uses the IViewObject interface to print a control?

    Probably doesn't, since I don't know what you're talking about :).

    What do you mean by "print a control"?

    As for resizing, I've put it in a container - and when the container resizes, I simply set the control's size equal to that of the container, and to the user it seems like it's resizing seamlessly just like any other control, so no problem there.

    Zitat von ingarh

    Thank you for your quick reply :-)
    I also have another question regarding the dictionary. What is the maximum number of words? Does the dictionary/spellchecker handle a dictionary of 300.000 words?

    My additional dictionary has 197.000 words - I'm using TextDynamic OCX, but I presume the underlying engine is the same. It works without a sweat.

    Writing into registry works, like this:

    Code
    lcSCPath="Software\WPCubed\WPSpell\SpellCheck-Files"
    	GoApp.oRegistry.SetRegKey("DCT0",Realpath("english.dct"), lcSCPath, HKEY_CURRENT_USER, .T.)
    	GoApp.oRegistry.SetRegKey("DCT1",Realpath("words.dct"), lcSCPath, HKEY_CURRENT_USER, .T.)
    	GoApp.oRegistry.SetRegKey("DCTs",2, lcSCPath, HKEY_CURRENT_USER, .T.)
    	GoApp.oRegistry.SetRegKey("DCTs.Disabled",0, lcSCPath, HKEY_CURRENT_USER, .T.)
    	GoApp.oRegistry.SetRegKey("User",0, lcSCPath, HKEY_CURRENT_USER, .T.)

    Now what's this RealPath() thing? It's where I instantiate a FileScripting object to get the file's full path name. VFP's FullPath() returns everything uppercase, and the spelling checker component just had to be case sensitive when reading the registry... !?

    OK, solved, move on.

    OK, so far so good - it all works.

    Now for the next quest. My app is branch specific, delivered with a huge text database. The purpose of including the OCX is to provide text editing within the app. This touches spelling in a certain way - the user may copy and paste a lot of text from the database into the editor, and I don't want that part of the text to have spelling errors. So I extracted all the words we have, and compiled a dictionary. And that works, well, on my development machine.

    When it gets to delivering the installation CDs, how do I tell the spell checker to use both english.dct and my.dct without user intervention? Do I have to insert the values into the registry, or is there a set of wpa commands to do that? I haven't found any spelling-related wpa, so I better ask here.

    Zitat von wpsupport


    I think it would be better before - than it is assured that the correct interface pointer is passed to the engine. (The interface is called directly from the DLL, not from the OCX - except for the property change event)

    I think it would be even possible to create a replacement of the OCX in FoxPro - similar to the .NET assembly. I am not so sure about using this control in a container (if this is what OleControl is). I would rather expect to use it directly with CreateObject.

    Tried it all - and nope, OleControl is the only way to go. It's a host to OCXes, and doesn't have any visual presence of its own, it's just a wrapper object, which probably handles the communication to the OCX.

    I can createobject() it, but it stays invisible - as does any other createobject()ed thing in VFP, so you can set any of its stuff before showing it. When you're done, you either set oObj.visible=.t. (true), or do oObj.Show() if it has such a method. Haven't found any way to force oWPT to be visible - and I need it in a form anyway. The end user should be able to launch a dozen of these if he wants, and the form is the ideal wrapper for this - it has the caption I can set etc.

    However, I can't add such an object to a form, it reports "Object class is invalid for this container" - which is a Fox error telling me that it just won't accept that as a member of the form. It does, with the oleControl wrapper.

    Zitat von wpsupport

    Maybe check when you attach the interface - if it before or after the DLL is loaded. (assign to property DLLName to load the DLL from a specific directory. You need to add such code anyways to make it possible to deploy the application)

    I tried instantiating the control first, then attaching the event handler, then setting the dll, options, password etc - still the event handler doesn't react at all. I've added a little "debugout program()" into each method, which is the most lightweight debugging device - a pretty much console output of the name of the current routine's name into a window of the debugger - and still nothing shows there.

    Well, never mind - since everything else seems to work, and I've found a way to override what I needed, problem solved.

    If you get anyone else using TextDynamic in Fox, you have my email address.

    I wouldn't know why neither works - the event handler doesn't catch any events, and the event code in the control itself doesn't pass any usable parameters. I'm just happy I have a solution for my immediate problem.

    Maybe there need to be some additional settings in the TLB, I don't know, never went that deep. I know that there were several producers of OCXes who had to do a few more things to make their controls work with VFP. You may contact DbiTech, they've made sure all their OCXes work with VFP.

    Zitat

    Maybe check when you attach the interface - if it before or after the DLL is loaded. (assign to property DLLName to load the DLL from a specific directory. You need to add such code anyways to make it possible to deploy the application)

    I did it after - I'm actually using VFP's OleControl, which is a generic host for OCXes, and I've put all the settings (dll, password, layout) inside its .init, which happens before it's added to the form.

    You think it may be different if I hooked into it before loading the dll?

    The EventHandler code is a VFP class which implements the interface of the COM object which it should track. The interface code is generated by object browser (which reads the tlb), and looks like this:

    Code
    DEFINE CLASS WpEvents AS session	IMPLEMENTS IWPDLLIntEvents IN "F:\PROGRAM FILES\TEXTDYNAMIC\REDIS\WPTDYNINT.OCX"	PROCEDURE IWPDLLIntEvents_OnKeyPress(Editor AS Number, Key AS NUMBER @) AS VOID	debugout program()	ENDPROC	PROCEDURE IWPDLLIntEvents_OnLoadText(Editor AS Number, filename AS STRING) AS VOID	* add user code here	ENDPROC*-- etc etc, one method for each published method or property set/getEndDefine


    and it's bound to the instance like this:

    Code
    this.NEWOBJECT("oWpt", "textdyn","libs\textdynwrap.vcx")this.owpt.visible=.t.thisform.AddProperty("oHandler", NEWOBJECT("WpEvents","tmp.prg"))EVENTHANDLER(this.owpt.object, thisform.oHandler)

    So far so good, but none of these ever fire. I got some other eventhandler code which detects Windows messages - this is how it knows when the user alt-tabs into or out of the app - and that works.

    Anyway, I got this to work by attacking it from the opposite direction: if I can't get the parameters out in a decent fashion, I can push them in. I'll add my own buttons for the functions I need to override, and have some code like this in them:

    Code
    thisform.owpt.wpaProcess("DiaSaveAs","dox\trtemrte.rtf")


    Tried this while suspended (in the debugger), and it worked like a charm. Now I just need to remove a few buttons from the .pcc file and draw my own somewhere by the top of the form, and I'm as happy as the little monkey when the big monkey is out :).

    Zitat

    Can you translate this example to FoxPro?

    I can, but it wouldn't work - the equivalent of the "Dim ... as" serves only for Intellisense to read the TLB so its properties show up in the editor. However

    Zitat

    theButtons = Def

    would only create a new reference to the object, tried that already.

    There's another approach I'm considering, the eventhandler interface - and I almost got it to work, except that for some reason form's .init (equivalent of onLoad, fires after all the form's objects are instantiated) didn't quite fire (which is a first) and eventhandler() call was the last line there. I'll try to move the code elsewhere and see what happens. I assume that I either have to move the call to before this.oWpt.SetLayout(), or to move it into .owpt.init() or something like that - into some place that I know that code executes. It could be that the control itself initalizes somehow in a manner that steals the focus from VFP's code, or whatever. That's something to do today.

    Zitat


    About the copyright protection: I plan to introudce a set of properties to protect the text, including disabling of the internal save and print dialogs and also by encrypting the clipboard contents with a password which is randomly created for the editor instance. Clearing the clipboard when focus changes can frustrate the people I think - if they just switch to a different program, look something up or so and than come back and cannot paste.

    No, I plan to do this other way around - they will be able to paste into, they just won't be able to copy out of the app. That's customer's requirement and the users will be notified. I'd also like to see a drag'n'drop into the control (text, not just images), but that'd be the icing on the cake.

    As for the saving and printing - like I said, printing is fine as long as it's not to a PDF printer, and for saving and loading I'd use one of the encryption schemes that are already in use in other areas of the app.

    Say, if I manage to intercept printing, does the wpa="print" call the print dialog by itself, or does it go to the currently selected printer? I figure I'd find that by myself, but since you're already here... :)

    Zitat

    So you can use the property "Name" - you need to set in in the PCC file of course.

    If you cannot work with the interface please try to assign it to a local or global reference variable of the type IWPDllButton.

    Still no good - I tried with any of the properties listed, for each one I get the "Not implemented" error.

    And I tried to let Fox know its interface by

    Code
    LPARAMETERS editor, def as "{8F6368D4-20D7-47C0-BF15-BE84DC7A19B2}"

    but still no dice. It just seems that the interface for this is not published in the OCX - I can see it in object browser, but it's not bolded, i.e. not exposed. The object browser is a separate app, which reads the information from somewhere (probably ocx itself), but this doesn't help me to retrieve the info from this parameter.

    Setting the type of a variable does nothing in VFP - its variables can change type at will. And its COM uses late binding. Just need the interface exposed somehow.

    Is there a setting somewhere, to change the way this parameter is passed?