How to handle Retrieval arguments type mismatch error? - powerbuilder

Retrieve function when called with wrong parameter type shows error message. The error message does not show which DDDW, datawindow control or dataobject was not retrieved. The ugly error message show no sign of any datawindow control i can go check immediately. I have to go through code. Is there any way i can see (at runtime ) what datawindow control or DDDW causing error?
PowerBUilder 12.5

I would advise to follow the steps that you take to end up in this situation: which is open, and what causes that problem to appear. This can be done by following the various objects in PB. Personnally, I start from the menu to see what window(s) are opened from there.
Once you know the object that fires that message, use the searchpossibility that you find by right clicking on the object (in the worst case, right click on the library or target) to search over all objects. This will give you a list of all places where retrieveis used.
Another possibility is to use the retrievestart event in datawindow control to code something (messagebox or some kind of logging). That event is fired everytime the method retrieve is used for the specific datawindow control. This is especially interesting if several (or all) your windows inherit from a common ancestor.
Hope this helps.

Related

TDrawGrid OnSetEditText fires twice + Inplace Editors + TCustomGrid

I have (in D2010) a TDrawGrid on my form. Im handling my OnDrawCell, OnSetEditText, OnSetEditText etc alls gfine there.
If however in the specific situation that you go in a cell that has some text, highlight the text in its entirity, then type some character to replace. Now the OnSetEditText event fires twice in a row from one keypress, firstly with a blank string, then again with a string containing the character you type. Is this correct or a bug? I would have expected to just get the event fired once with the string containing my single character typed.
I am using OnSetEdit text to set other class properties which does stuff like validation, so when the above situation causes my other code to consider momentarily my class properties to be invalid, before imediately being set back to valid again on the 2nd fire, its still having undesriable consequences though and i want to stop that 1st event firing, or get the bets workaround I can.
Now whilst on the subject of grids, may I appeal to you folks for an helpful tips in the folling things. I am fairly new to deplhi from c# (I'm going the other way!) but Im finding the docs to be pretty thin on the ground, and am getting surprisingly limited results googling for things, so your help is really appreciated.
1) Custom Inplace Editors for TDrawGrid - any tips or good links appreciated!
2) For custome inplace editors, am i better off with TDrawGrid or descending my own control from TCustomGrid and going from there?
3) TCustomGrid. I am getting nowhere here... If I create a new component and descend from TCustomGrid I just get an 'abstract error' when i place it my form. Therefore further experimentation is very much canclled - an advice on just even getting started with TCustomGrid appreciated!
My plan is first to get combo boxes (in virtual mode) working as cell editors. Thats a standard VCL control. Afterwards I plan to create my own control based around a virtual combobox but with a search thing at the top to filter the list down (a bit like in the Delphi IDE Tool pallette), and use this component as inlace editor if possible. Im a fair way off that right now! Thanks all
Edit: Remy - Here are my two call stacks from beak point in OnSetEditText. Left is first fire with the empty string, right is 2nd fire with correct string value. The 5 truncated lines in the middle are all references to comctl32.dll in both. Ty.
Click here for call stack
The OnSetEditText event is fired whenever the inplace editor's contents are updated for any reason, when a drop-down editor is closed after selecting a different value, a drop-down editor is double-clicked on, or a drop-down editor's RestoreContents() method is called. So you very likely are getting multiple actions updating the editor one after the other. I suggest you put a breakpoint inside the TCustomDrawGrid.SetEditText() method and see what the call stack looks like each time the event is being fired.
Regarding #2, it does not matter what you derive from. Any TCustomGrid descendant can have a custom inplace editor. Simply override the virtual CreateEditor() method.
Regarding #3, if you are getting an abstrct error when deriving from TCustomGrid directly, then you did not override its abstract methods correctly.
A grid already natively supports a drop-down inplace editor that mimics a combobox. Look at the TInplaceEditList class. You can use the OnGetPickListItems event to fill in the editor with values. Also, have a look at how TValueListEditor implements its custom editors.
On "abstract error"s:
In Delphi the cause of an "abstract error" is the fact you try to instantiate a class with a non-overridden virtual abstract method. If you see such errors, you should look at the definitions of the parent object (TCustomGrid in this case), to see which of its methods are virtual abstract, then you should override those function in your descendant class.
Note, that Delphi (poorly) only requires you to override functions that gets called, therefore lots of coders out there don't even know the cause of the mentioned behavior.

How can you make an MFC application with an HTML view consistently accept drag-dropped files?

I'm trying to decipher CHtmlView's behaviour when files are dragged into the client area, so I've created a new MFC app and commented out the CHtmlView line that navigates to MSDN on startup. In my main frame, I've overridden CWnd::OnDropFiles() with a function that shows a message box, to see when WM_DROPFILES is sent.
OnDropFiles() gets triggered on all except the first time you try to drag a file into the application. Uniquely, that first time appears to be interpreted by the application as a request to display the data in the file rather than a request to open the file. I've tried overriding OnDrop() from the view class, but it's never called.
Why is the first time different? How can I catch all attempts to drag a file into my app?
This is part of the underlying WebBrowser control behaviour. CHtmlView sets RegisterAsDropTarget to true by default, which means the control intercepts the drop operation and performs its own processing.
If you want to inhibit it, call SetRegisterAsDropTarget(FALSE) in your OnInitialUpdate implementation. All drop operations will then interact with the main window.
Preface: I'm extrapolating from documentation I've found, and am not concerned if I'm wrong. Please make sure the following explanation makes sense, ie try it, before voting-up my answer or accepting it :)
After Googling OnDropFiles, I discovered that it's inherited from the CWnd class: (MSDN page)
According to that MSDN article:
Parameters
hDropInfo
A pointer to an internal data structure that describes the dropped files. This handle is used by the DragFinish, DragQueryFile, and DragQueryPoint Windows functions to retrieve information about the dropped files.
Quoting later:
"The framework calls this member function when the user releases the left mouse button over a window that has registered itself as the recipient of dropped files.
"Typically, a derived class will be designed to support dropped files and it will register itself during window construction.
This member function is called by the framework to allow your application to handle a Windows message. The parameters passed to your function reflect the parameters received by the framework when the message was received. If you call the base-class implementation of this function, that implementation will use the parameters originally passed with the message and not the parameters you supply to the function."
That appears to indicate that until the function has been registered, it won't work 'as expected'.
Therefore, I believe that what's happening is that the first time you drop something onto the CHTMLView, it registers itself, and only then 'works as expected'.
If my understanding is correct, then a new question is raised, which is how can you force the registration of the View. From the related links on the MSDN Technote, it looks like you can force DragAcceptFiles (see here) to run, which would otherwise be triggered when the drop event finished.
What I would recommend is to switch to HTMLayout -- it's waaaay better than CHtmlView.

How do I setup a callback mechanism for RichEdit in win32

In win32, how do I setup a callback mechanism for RichEdit I have not created myself?
PART 1
I'm reading from a textedit field in another application's GUI. This works just fine now, except after the first read I'd like to fetch only new or modified lines. In GTK+ or Qt I'd just install a callback on some signal the field edits when its changed, but how does it work on Win32?
My MSDN searches result with nothing useful, probably because I don't know the exact term to search for. The class of the textedit is RichText20W, and it has some messages that are probably used somehow, though that article just discusses using them for the parent of the class.
PART 2
Also, if there is no such "text changed, here is the newly inserted text" callback which returns the new content immediately, I need some way to easily detect what is new. From top-of-my-head:
Have a marker at the end of the text block we've read, and only read between that and the end.
Store what we've read previously, and after a second read, remove the duplicate part from the latter to have the newly inserted stuff.
Option 2 might not be viable, since the textedit can contain any amount of text. The marker part sounds doable, but yet again, my feeble Win32 skills and horrible Win32 function names prevent me from finding the right way to do it.
Note that all these must be doable for a textedit I do not own and have not created, they belong to a third party process.
Code samples in C++ highly appreciated.
Disclaimer
Obviously, if there is some better way of doing it, let me know. I only assumed callback would be the way to go based on my previous experience with GTK+/Qt. Feel free to show me the path :)
Win32 controls don't work on message-specific callbacks that you can subscribe to. They just send messages to their parent window when something happens, in this case EN_UPDATE, EN_CHANGE and all that. Even these events don't tell you what text changed. They only tell you that it did change.
You could subclass the parent, but the documentation for SetWindowLongPtr explicitly says you "should not subclass a window class created by another process." Something like this is probably possible with hooks, but I haven't used them enough to say for certain how you'd actually do it.
I realize it's an old post, but this article seems to be doing something similar.
Based on Joel's answer, I quit looking for callbacks and just made a small class that hooks itself (not by a real API hook though) to the richedit and polls it once a second for content length, and if it has changed since the last poll, it asks for the content, compares that to previous known content and emits a signal with the changed content.
This seems to work OK for this purpose, but if someone knows a better way still (some real and tested way of doing it via API hooks or something), please post.

Special case: wrong order of updates for fly-away

How can I track down the location of the "Special case: wrong order of updates for fly-away!" error?
This error message is defined in Datasnap.DSIntf as
const
...
ERRCODE_FLYAWAY_WRONGORDER = 13; { Special case: wrong order of updates for fly-away }
...
DBERR_FLYAWAY_WRONGORDER = ERRBASE_ALC + ERRCODE_FLYAWAY_WRONGORDER;
but nowhere else in the Delphi sources can I find references to substring FLYAWAY_WRONGORDER.*
My intention was to compile with debug dcu's, then put a breakpoint on the line where the exception is raised and check the call stack UP to find the cause.
I'm currently stepping DOWN into the code until the error occurs, but that is less efficient (complex app).
Placing a TApplicationEvents with a breakpoint in its OnException handler does not give me usable call stack information:
So, how can I (efficiently) track down the place where this error is generated?
Background on what is going on:
Form uses DevExpress TcxScheduler connected to TcxSchedulerStorage component in datamodule, connected to nested TClientDataSets
Code saves all changes to these datasets (ApplyUpdates)
In BeginUpdate/EndUpdate for these DevExpress components, I then insert, delete and update records in these datasets, move around while doing so, even change parent IDs in detail datasets so that they drop from the current detail dataset 'in view'.The error occurs when I Edit, then Post a record doing exactly that.
Delphi Tokyo 10.2.3, Win32 app
Any other info on that error message is welcome, I was not able to find anything.
I actually 'fixed' the error by calling ApplyUpdates for the master dataset in a few places, but since I'm not really sure about the cause I want to investigate this further. So my question is not How do I fix the error in my code, it is How do I find the error in my code?
* There is a CheckForFlyAway routine in TCustomADODataSet.InternalPost in Data.Win.ADODB but we don't use ADO, I cannot set breakpoints in those routines.

Unreasonable error when double-clicking on Object in Design-time in Delphi

Ok, here is the issue:
Recently I hit an problem that I was not able to use Accelerator Keys ( a.k.a HotKeys ) on Buttons inside GroupBox. Just a minute ago I found out why, but now only problem is that this reason makes me even more puzzled than before, which is that Such button with accelerator cannot be found on Form. Effect is that when I double click to affected buttons with double-click while in Design-time, I get error "Property and method are not compatible".
MethodName is VKPInputBtnClick, that is actually declared as function, not as Method in Unit.
What makes me puzzled is that I have not assigned OnClick event handler for VKPInputBtn to any Method at all!
How it is possible that I can compile program and have no run-time problems ... but in Design-time double click on button has such annoying issues ....
Any solution? Reinstall of IDE?
Any help much appreciated ...
Double-clicking a control that doesn't have its default event property set causes the IDE to assign that property. (It's not just a shortcut for going to the code editor; that's F12.) The IDE searches the source code for a function with the desired name. If it doesn't find one, then it creates a method in the containing form and assigns it to the component's event property. But if it does find something with the right name, it attempts to assign it without creating anything new.
The problem, apparently, is that the thing the IDE finds in your case isn't compatible with the event it appears to go with. Probably a bug — it shouldn't select non-methods — but a rarely encountered one given the low frequency with which humans choose the same name for standalone functions as the IDE chooses for event handlers.
You have several options:
Rename VKPInputBtnClick so it doesn't look like it's the OnClick event handler for the VKPInputBtn control.
Make VKPInputBtnClick be a method of the form class.
Manually declare a new VKPInputBtnClick method in the form class, and maybe the IDE will select it instead of the standalone function.
Type some other name into the OnClick property in the Object Inspector, and then double-click it (or press Enter). The IDE will create a method with that name.
Try deleting the handler from the .pas file from the declaration and the implementation sections (or copy somewhere if they contain code). Then try to recreate the handler for the button. Sometimes the IDE can get out of sync and all that can be done is to reset back to a known state.
If that doesnt work see if you can close the form and reopen, or remove the handler from the .dfm file.
The components work differently in design and in runtime. Double clicking on a button in desgintime creates and adds an OnClick handler. That explains why the behavior is different.
Hopefully I understand your question correctly. You have a component on your form, and you are not able to assign a correct eventhandler because the automatically created eventhandler is a different type than the expected eventhandler?
In that case, create your own eventhandler and assign it. You can even assign it in the OnCreate of the form. If assignment trough the dfm does not succeed.
If this turns out to be a real bug, don't forget to file it with Embarcadero. You can access the QA app via the tools menu in the IDE or go to the website.
Anyway, Question is answered and it is clear that this error message should be a RAD Studio XE bug because IDE in wrong way compares actual and needed properties for Object.
Thank you all very much for input.
EDN QC Case: #89543
Notes:
This is approach I use to use Accelerator functionality for VKPInputBtnCLick function.
- Use Message form this code snipp: Alt key handling algorithm
- Change VK_TAB to VK_LMENU ( left ALT )
- Once ALT message is captured, set global unique value to variable
- In FormKeyPress event handler, check if unique global variables value match the one I set before
- Execute function.
Hope it helps to others willing to do this. Also, some more sleek and clean way to achieve this functionality are welcome, too.
Not setting Question as Answered yet.
is actually declared as function, not as Method in Unit.
Method handlers must be procedures, not functions. Hence it doesn't work.
As Toby said a long time ago (but you obviously didn't listen):
Try deleting the handler from the .pas file ...
Then try to recreate the handler for the button.

Resources