Lazarus - child modal form is non-responsive - forms

This is only part of a larger project. I have a text box on a form and when the command button next to it is clicked, I want to bring up a form that looks aligned to the text box. The idea is to make it look like a drop-down box. But the only thing is that this 'drop-down' is another form and a modal one.
This is what I've done so far and the form shows fine.
procedure TfrmSetupTaxes.cmdChangeParentClick(Sender: TObject);
var
Res : Integer;
frmPopUp : TForm;
begin
frmPopUp := TfrmTreePopUp.Create(nil);
frmPopUp.Parent := Self;
frmPopUp.Top:= self.rp.Top + self.EditItemCat.Top +
self.txtSelParentName.Top + self.txtSelParentName.Height + 3;
frmPopUp.Left:= self.rp.Left + self.EditItemCat.left + self.txtSelParentName.Left;
Res := frmPopUp.ShowModal;
end;
Note: 'rp' is a panel and 'EditITemCat' is a tabsheet. These are merely used for positioning.
Now, here's my problem...
Although the form shows up, it seems frozen. It does not respond, neither does the parent form. Since I'm on the IDE, I just close it.
Can someone please show me what I'm missing here?
Thanks!

What you're missing is how modality works. When there's a modal window in an application, you cannot interact with other windows because these other windows are disabled.
When you call ShowModal on frmPopup, the TfrmSetupTaxes form is disabled for the above reason. Since you've made frmPopup a child of frmSetupTaxes, it also gets disabled.
You cannot workout this design by using modality, you have to devise another mechanism.

This is one of the best findings, at least to me ;)
After a lot of digging and direction, I realised that it was beyond me. I could not figure out the 'right' way that would work for the various OSs (at least Windows and Ubuntu).
Finally I hired an expert (no, not from any forum site) and paid him to show me this. And with the hope that it may help other developers, I thought it would be best to post it here.
Before the answer, I need to give a big thank you to Sertac-Akyuz who showed me that certain things were impossible. I also found through their links that there were some solutions but they did not fit my needs.
Now, before the answer, here are my rules I had to stick to.
I should not use Any Windows-specific functions or APIs because I want to be able to port my work between Windows and Ubuntu (at least for now).
There no MDI forms in use. Again for cross-platform reasons.
There are no 3rd party plugins or products in use.
Now the answer...
procedure TfrmSetupTaxes.cmdChangeParentClick(Sender: TObject);
var
Res : Integer;
frmPopUp : TForm;
pt: TPoint;
begin
frmPopUp := TfrmTreePopUp.Create(self);
pt := txtSelParentName.ClientToScreen(Point(0, 0));
frmPopUp.Top := pt.y + txtSelParentName.Height;
frmPopUp.Left := pt.x;
Res := frmPopUp.ShowModal;
end;
And that's it!
The key was in NOT setting the parent property of the popup. Then using ClientToScreen (a function I didn't even dream of using). It does the job beautifully.

Related

Lotus Notes - Save mail to file with OLE

I am accessing Lotus Notes via OLE, and this is how I retrieve the selected mail:
try
UIView := FLNotes.CURRENTVIEW; // am I in a view or in an opened document ?
if VarIsClear(UIView) then begin
try
aDocument := FLNotes.CURRENTDOCUMENT.Document;
except
raise;
end;
end else begin // any selected mails in view ?
UIDocuments := UIView.DOCUMENTS;
for counter := 1 to UIDocuments.Count do begin
if counter = 1 Then
aDocument := UIDocuments.GETFIRSTDOCUMENT
else
aDocument := UIDocuments.GETNEXTDOCUMENT(aDocument);
end;
end;
finally
UIView := Unassigned;
UIDocuments := Unassigned;
aDocument := Unassigned;
end;
I have the reference to the particular mail in aDocument. Now I would like to save every each mail (on the disk as a file, not inside Lotus Notes), but I didnt find the right method to use with OLE.
I have found this Notes Commands, but I didnt figure out whats the syntax for OLE access. I tried it like this: aDocument.Command("FileSave", "Test.eml"), and I tried also lot of other combinations with Save but none of them worked. So maybe somebody did this already or has a tip where I could look for a solution
Thanks
Regards
Save operations in Notes will save a document in an NSF file, not the filesystem. It's an Export operation you would be looking for.
The FileSave command saves a currently open-for-edit document in the
Notes UI and saves it to the NSF file that it was opened from.
The Save method similarly does a back-end save - i.e., it bypasses the UI operations, takes the in-memmory representation of an existing Notes document (not necessarily the one that is current in the Notes client), and saves it to the NSF file that it was opened from.
Back to the subject of Export operations, as far as I know, there is no supported Export method for .eml files. Although the Notes client can save a .eml file if you drag a message from a view and drop it on your desktop, I don't believe there is any supported method in any of the supported Notes APIs for automating this process. (In theory, I imagine that one might be able to use the Windows API to send the appropriate event messages to the Notes client in order to make it think the user is doing a drag-and-drop operation, but that's way beyond the scope of what could possibly be addressed here on StackOverflow.)
It seems that there is a way to save the mail as an eml file (actually any file that you want, but since .eml is what I need I will use that). So for any case somebody may need it here the code :
try
oleSession := GetActiveOleObject('Notes.NotesSession');
except
oleSession := CreateOleObject('Notes.NotesSession');
end;
path := '...Somepath.../Mail.eml';
oleDB := oleSession.CurrentDatabase;
oleSession.ConvertMIME := false;
oleView := GetSelectedMail; //the code for this is in the first post
oleDoc := oleView.GetFirstDocument;
oleDoc.converttomime(1);
mime := oleDoc.getmimeentity;
oleEmailText := oleSession.CreateStream; // create a stream to fill it with the data
oleEmailText.open(path, 'us-ascii');
mime.GetEntityAsText(oleEmailText); // write inside stream
oleSession.ConvertMIME := true; // put this flag back to its original state - per default its true -
Just as a side note, with this method attachments are missing from the saved mail. But since I separate them and save inside another folder, its not a big issue for my case
Regards

Is it possible to use a control without putting it on a form in VB6?

I'm pretty sure about the answer to this, but I'm trying a variety of things to get a very stubborn project to work. One idea was to try to run code through a control without defining it on a form.
So, for example, my original code looked like this:
frmProcess.MyViewer.MaxPageSize = 100
frmProcess.MyViewer.ResetPages
frmProcess.MyViewer.AddPageToView "C:\TestPage1.txt"
I've changed it to:
Dim objViewer As MyViewer
objViewer.MaxPageSize = 100
objViewer.ResetPages
objViewer.AddPageToView "C:\TestPage1.txt"
I get an error window with "Run-time error '91': Object variable or With block variable not set".
But there doesn't seem to be a way to 'set' this control. Is this just impossible, or is there another way to do it that doesn't require a form?
EDIT: I ended up abandoning this entire path of activity, as an alternate solution was found that got around the problem I was having with this form freezing. I don't want to delete this question in case someone else comes along and can benefit from the answers, which are potentially useful.
Try this on a form.
Dim objViewer As MyViewer
Set objViewer = Controls.Add("MyViewer", "MyViewer1")
objViewer.MaxPageSize = 100
objViewer.ResetPages
objViewer.AddPageToView "C:\TestPage1.txt"
I've had similar situations in the past. If all else fails and you have to use a form you can do something crude like
1) Set the .Left property of the control to a negative number (like -10000) so the control doesn't appear on the form, the user can not see it
2) Make the entire form not visible..
ActiveX controls normally expect a number of services from their containers, for example persistence. They are also "packaged and marked" in ways that set the kinds of instantiation they support.
See Introduction to ActiveX Controls.
While it is perfectly possible for a control to be created in such a way as to make many of the available services optional, most controls are created from template code that requires a number of them. And most controls that are "visible at runtime" are going to require container services.
However that doesn't mean a control can't be designed to support containerless instantiation. A well known example of such a control is Microsoft Script Control 1.0 (MSScriptControl.ScriptControl) which can be used either way.

Anyone have any idea how TabStop works in iText 5.5.0

I'm still trying to learn iText and have a few of the concepts down. However I can't figure out what TabStop is or how to use it. My particular problem is that I want to fill the end of all paragraphs with a bunch of dashes. I believe this is called a TabStop and I see the class in the itext jar but I have no clue on how to use it. I must be searching the wrong thing on google, but I've come up with nothing. The iText in Action book also doesnt seem to even know of the existance of this class so any help is much appreciated!
Please take a look at the ChunkTest class in iText's test suite. It contains several use cases of the tab stop functionality. For instance:
java.util.List<TabStop> tabStopsList = new ArrayList<TabStop>();
tabStopsList.add(new TabStop(100, new DottedLineSeparator()));
tabStopsList.add(new TabStop(200, new LineSeparator(), TabStop.Alignment.CENTER));
tabStopsList.add(new TabStop(300, new DottedLineSeparator(), TabStop.Alignment.RIGHT));
p = new Paragraph(new Chunk("Hello world", f));
p.setTabSettings(new TabSettings(tabStopsList, 50));
addTabs(p, f, 0, "la|la");
ct.addElement(p);
The TabStop functionality was introduced after the iText in Action books were written. They'll be documented in one of the new books.
For another example, see http://developers.itextpdf.com/examples/itext-building-blocks/tabbing-examples

Unicode and PDF tooltips / messageboxes with iTextSharp

I need to find a way to add a quite long string in a quite small space in a PDF document.
I am using iTextSharp. I have already tried adding comment annotations (balloons) with PdfAnnotation.CreateText() and I didn't like the way they looked/worked. It made the page too heavy (I had many comments per page) and their behavior was odd in many ways (thank Adobe for that).
Now I was thinking of adding some simple tooltips on 'chunks' in the page or popping-up messageboxes with javascript (like illustrated here : http://www.codehacker.com/ITEXTSHARP/chap15.aspx#). To my great disappointment however, it seems that Acrobat (?) doesn't support Unicode characters in those situations. E.g. I do this:
var javascript = new PdfAnnotation(
w, 200f, 550f, 300f, 650f,
PdfAction.JavaScript("app.alert('" + "Αρνάκι άσπρο και παχύ!" + "');\r", w));
chunk.SetAnnotation(javascript);
...and, in the best case, a messagebox with gibberish pops up when the user clicks on the chunk.
Is there any setting for making Unicode acceptable for the code above or another way to do what I want?
EDIT:
I have now seen this: https://stackoverflow.com/a/163065/964053
and I've tried modifying my code like that:
var javascript = new PdfAnnotation(
w, 200f, 550f, 300f, 650f,
PdfAction.JavaScript((char)0xFEFF + "app.alert('" + "Αρνάκι άσπρο και παχύ!" + "');\r", w));
chunk.SetAnnotation(javascript);
But nothing seems to change...
EDIT2 :
Using octal representation e.g. (\141) doesn't seem to help either...
EDIT3 :
This seems to work nice until you double clink on it, but I need to make the tooltip size itself based on the contents size:
var lToolTip = PdfFormField.CreatePopup(
w, new Rectangle(tc.Left, tc.Bottom, tc.Right, tc.Top), val, true);
chunk.SetAnnotation(lToolTip);
The rectangle provided doesn't seem to be used in any way...
Any ideas?
I don't know what PdfFormField.CreatePopup() is supposed to create, but I see a small mark on my page that displays a popup when you hover the mouse over it.
I'm kind of lost in your edits, it's not clear what works for you and what doesn't, but regarding the unicode problem in JavaScript: are you aware that there are two versions of the javaScript() method?
See javaScript(java.lang.String, com.itextpdf.text.pdf.PdfWriter, boolean)
If you add the boolean value true, the JavaScript string should be interpreted as Unicode. If this doesn't solve your problem, I'll delete this answer, and if you clarify your question (cutting away the irrelevant parts), I'll do another attempt.

Integrate Stack Overflow into IDEs?

Okay, this is just a crazy idea I have. Stack Overflow looks very structured and integrable into development applications. So would it be possible, even useful, to have a Stack Overflow plugin for, say, Eclipse?
Which features of Stack Overflow would you like to have directly integrated into your IDE so you can use it "natively" without changing to a browser?
EDIT: I'm thinking about ways of deeper integration than just using the web page inside the IDE. Like when you use a certain Java class and have a problem, answers from SO might flare up. There would probably be cases where something like this is annoying, but others may be very helpful.
Following up on Josh's answer. This VS Macro will search StackOverflow for highlighted text in the Visual Studio IDE. Just highlight and press Alt+F1
Public Sub SearchStackOverflowForSelectedText()
Dim s As String = ActiveWindowSelection().Trim()
If s.Length > 0 Then
DTE.ItemOperations.Navigate("http://www.stackoverflow.com/search?q=" & _
Web.HttpUtility.UrlEncode(s))
End If
End Sub
Private Function ActiveWindowSelection() As String
If DTE.ActiveWindow.ObjectKind = EnvDTE.Constants.vsWindowKindOutput Then
Return OutputWindowSelection()
End If
If DTE.ActiveWindow.ObjectKind = "{57312C73-6202-49E9-B1E1-40EA1A6DC1F6}" Then
Return HTMLEditorSelection()
End If
Return SelectionText(DTE.ActiveWindow.Selection)
End Function
Private Function HTMLEditorSelection() As String
Dim hw As HTMLWindow = ActiveDocument.ActiveWindow.Object
Dim tw As TextWindow = hw.CurrentTabObject
Return SelectionText(tw.Selection)
End Function
Private Function OutputWindowSelection() As String
Dim w As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
Dim ow As OutputWindow = w.Object
Dim owp As OutputWindowPane = ow.OutputWindowPanes.Item(ow.ActivePane.Name)
Return SelectionText(owp.TextDocument.Selection)
End Function
Private Function SelectionText(ByVal sel As EnvDTE.TextSelection) As String
If sel Is Nothing Then
Return ""
End If
If sel.Text.Length = 0 Then
SelectWord(sel)
End If
If sel.Text.Length <= 2 Then
Return ""
End If
Return sel.Text
End Function
Private Sub SelectWord(ByVal sel As EnvDTE.TextSelection)
Dim leftPos As Integer
Dim line As Integer
Dim pt As EnvDTE.EditPoint = sel.ActivePoint.CreateEditPoint()
sel.WordLeft(True, 1)
line = sel.TextRanges.Item(1).StartPoint.Line
leftPos = sel.TextRanges.Item(1).StartPoint.LineCharOffset
pt.MoveToLineAndOffset(line, leftPos)
sel.MoveToPoint(pt)
sel.WordRight(True, 1)
End Sub
To install:
go to Tools - Macros - IDE
create a new Module with a name of your choice under "MyMacros". Or use an existing module.
paste the above code into the module
add a reference to the System.Web namespace (for HttpUtility) to the module
close the macro IDE window
go to Tools - Options - Environment - Keyboard
type "google" in the Show Commands Containing textbox. The SearchGoogleForSelectedText macro should show up
click in the Press Shortcut Keys textbox, then press ALT+F1
click the Assign button
click OK
This is all taken from Jeff Atwood's Google Search VS Macro post, just modified to search StackOverflow instead.
I don't think I'll be able to get any work done with SO integrated into an IDE. Its almost as bad, if not worst than integrating Digg/Reddit into an IDE.
In Visual Studio, you could add a shortcut to search for a highlighted term in StackOverflow. Jeff Atwood wrote about doing something similar with Google in his Google search VS.NET macro blog entry.
Using this approach would allow you to highlight a term or error message (or any other selectable text in the IDE), press the shortcut keys, and then see all the matching results on StackOverflow.
I'm sure there's a way to do this in other IDE's as well.
If StackOverflow can begin identifying the language that each code snippet contains, then I could see an code-completion/code-snippet plugin to an IDE that responds to a special syntax for performing searches on SO and inserting the code portion of accepted answers.
Eg: in my source I might type:
//# read an XML file
The //# syntax prompts the plugin to start a search and display a list of question titles. When I pick one, it inserts the code portion of the accepted answer.
I don't know about Eclipse, but for Visual Studio, if someone really wanted this they could easily add the SO RSS feed for the "Start Page News Channel" so the SO question list appeared in the start page, or even better, narrow it down with a tag (like for C#). It's not exactly "integration", but it would provide a quick look at recent things with extremely little effort. However, not sure how "useful" it would be.
You have the RSS plugin for Eclipse to read the StackOverflow feed.
But I'm with you, a SO Eclipse plugin would be really cool.
You could just set it as your Start Page in Visual Studio.
Not sure what benefit this would provide... but to each his own.