I'm experimenting with something in Lazarus,trying to make a logic game for a class project.But as I'm not so good with delphi-I'm not sure what I'm doing wrong,but I get:
Error:Boolean expression expected,but got untyped
So basically what I'm doing is when a panel gets clicked it checks another panel if the caption is empty,and if it is it will change the color and the caption of the 2 panels. Now, I don't know if that's a possible syntax, but to me it seems as it should work. The code I have is:
procedure TForm1.Panel2Click(Sender: TObject);
begin
if panel1.Caption:='' then
begin
panel2.Caption:='';
panel2.Color:=clWhite;
panel1.caption:='Panel2';
panel1.Color:=clMaroon;
end;
end;
I would be very thankful to any kind of help or ideas.
Related
I'm trying to figure out how to change the background color of the bottom panel in the UNINSTALLER to match the colors I was able to set for the INSTALLER using information I found here: Inno Setup: How to change background color Unfortunately, I have been unable to find any way to extend that answer to include the uninstall page, too. It works great for the install, but when I test the uninstall I see this:
In the installer, when the background color of the lower pane changed, the background of the beveled label changed with it, but I cannot find a similar setting for the uninstaller. I looked at the list of CurPageID values and none seem related to the uninstaller, though I would expect it to either be listed or use the same settings as the installer. Sadly, neither seem to be true.
Can anyone please explain the right way to do this? Thanks!
EDIT: For anyone who doesn't want to look at the code from the linked article, here's the way it looks right now in my project:
procedure CurPageChanged(CurPageID: Integer);
begin
WizardForm.Color := WizardForm.InnerPage.Color;
end;
procedure InitializeWizard;
begin
WizardForm.Color := clWhite;
end;
I originally tried it without commenting out the lines in CurPageChanged, then I thought, why not ALWAYS set the color on a page change. Still, the uninstall pages have a gray lower pane. Apparently, the code doesn't affect them and/or they are not WizardForm pages.
EDIT: When asked to show the code I had tried, I added the block of code as it looked at the time. That block included some commented out lines that were part of previous attempts. Someone here decided that those previous attempts were NOT needed and removed them from my post. So may I ask, "Why is SOME of my failed code appropriate but other parts of it are not? Or should I post every single individual version of the functions in the 20-something times I tweaked them before giving up and asking my question?"
Uninstaller equivalent of InitializeWizard is InitializeUninstallProgressForm:
procedure InitializeUninstallProgressForm();
begin
UninstallProgressForm.Color := clWhite;
end;
An equivalent of CurPageChanged is CurUninstallStepChanged. The UninstallProgressForm is not available in initial usAppMutexCheck and final usDone steps.
Though you should use the InitializeUninstallProgressForm as shown above anyway.
In an application that displays a richedit control I would like to be able to visually distinguish soft returns (produced with SHIFT ENTER) from hard returns (produced with ENTER).
I already use the JVCL richedit and don't want to switch at that point.
How would you proceed to do that?
Microsoft Word may be an inspiration source, they display a ↵ sign for soft returns and a ¶ sign for hard returns at the end of each line.
I am just looking for hints, good ideas how you would tackle this project. I am not asking anybody to do my work, of course. :-)
I already use the JVCL richedit and don't want to switch at that point.
The JVCL rich edit control wraps the Windows rich edit control. The Windows rich edit control won't show whitespace the way you desire. It has no functionality to do so. If you want the control to display such symbols you'd need to paint them yourself and I doubt that can be done in a very effective and slick way.
It sounds like you are displaying code because you mention syntax highlighting. In which case a rich edit control is the wrong choice. You should use a control designed for displaying and/or editing code.
Although not a direct answer to your question, there is a possible solution to the problem you mentioned of needing to use both Richedit and Syntax highlighting in one control and that is the use of SynEdit.
SynEdit include some non-visual components that allow exporting syntax formatted text, one of those components is TSynExporterRTF.
Suppose you have a section of code which is in plain text inside your richedit and you want to syntax highlight that portion, you could select and copy that text to a TSynEdit and then export it to a TSynExporterRTF which will now contain syntax formatted text (assuming a highlighter has been defined correctly). Then you can simply write the data to a TMemoryStream and replace the selected richedit text with the now syntax formatted code.
To do this you can try something like this:
procedure SyntaxFormatRichEditText(RichEdit: TRichEdit; SynHighlighter: TSynCustomHighlighter);
var
SynEdit: TSynEdit;
SynExporterRTF: TSynExporterRTF;
MS: TMemoryStream;
begin
SynEdit := TSynEdit.Create(nil);
try
SynEdit.Highlighter := SynHighlighter;
SynEdit.Lines.Text := RichEdit.SelText;
SynExporterRTF := TSynExporterRTF.Create(nil);
try
SynExporterRTF.Highlighter := SynHighlighter;
MS := TMemoryStream.Create;
try
SynExporterRTF.ExportAll(SynEdit.Lines);
SynExporterRTF.SaveToStream(MS);
MS.Seek(0, soBeginning);
RichEdit.SetSelTextBuf(MS.Memory);
RichEdit.SetFocus;
finally
MS.Free;
end;
finally
SynExporterRTF.Free;
end;
finally
SynEdit.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SyntaxFormatRichEditText(RichEdit1, SynPasSyn1);
end;
If anything though, as others have suggested the requirements you need are likely out of scope as to what the Richedit controls can offer.
I've built a custom control that I'm trying to send input to. It will accept mouse input and report MouseDown, MouseMove and MouseUp correctly, but for whatever reason, it won't accept keyboard input. When I click on it, it doesn't receive focus, and any keys I press get interpreted by whatever control had the focus already.
This is probably something really simple. The first place I thought to look was in the ControlStyle property, but the only thing I can see in the helpfile about keyboard input is csNoStdEvents, which disables it, and my control doesn't have that. So what do I need to do to make it so my control can receive input focus?
A few things to try:
On MouseDown, call Windows.SetFocus(Handle). In my experience, the WinAPI function SetFocus often works better than the VCL's SetFocus method.
In response to the WM_GETDLGCODE message, reply with Message.Result := Message.Result or DLGC_WANTCHARS or DLGC_WANTARROWS or DLGC_WANTTAB or DLGC_WANTALLKEYS;
Could it be as simple as calling SetFocus on mouse down?
procedure TYourCustomControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);
begin
inherited;
if CanFocus then
SetFocus;
end;
Do you have WS_TABSTOP set? You don't have input focus without that, I believe. But this is based on a recollection from nearly 10 years ago, when I was writing my own syntax-highlighting code editor, for which I have long since lost the source.
{TWinControl.}TabStop := True; ought to do. A quick test app with a do-nothing component derived from TWinControl and displaying a dialog for key events seems to show that it makes all the difference.
I've checked the code for my control and I can't see anything that might stop this working. Are you calling "inherited" in the Create procedure?
I do handle the following, but nothing special:
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
Is the keystroke available at form level? That is, is KeyPreview turned on, and can you see the keystroke in the form's OnKeypress event? You can follow it from there in the debugger. Is the control (as Dan indicated) suitable for keyboard input? For instance, a TLabel, although it displays text, is a graphical control.
If I have a ButtonClick event which sets Cursor := crHourglass, Application.ProcessMessages, then use a TOpenDialog to choose a file, and then do something CPU-intensive, the cursor behaves differently depending on whether it is over the existing control when the Open Dialog closes. If the cursor is over the control then the cursor remains as an hourglass; if it's outside the application completely and then moved into the area while the intensive process is still taking place, the cursor remains as an arrow. One cannot click or do anything so it's confusing to the user to get an arrow but not be able to do anything with it.
Stepping through the debugger shows the Cursor is -11 everywhere it should be. Using Screen.Cursor instead of Cursor has the same effect.
Is there a solution?
procedure TMyForm.LoadButtonClick(Sender: TObject);
begin
Cursor := crHourglass;
Application.ProcessMessages;
if OpenDialog.Execute then begin
// Do something intensive
// Cursor = crHourglass here but what is displayed is different
end;
Cursor := crDefault;
end;
First, make sure to set the cursor only while the CPU-intensive operation is active. Don't change the cursor while choosing a file — you never see any other programs do that, after all.
Second, when you say Cursor in your code, you're referring to the form's property. You might wish to use Screen.Cursor instead so that your entire program displays the same cursor.
Third, there's no need to call Application.ProcessMessages. Messages are going to be processed as soon as you display a dialog box anyway, and besides, there are no particular messages you need processed.
Finally, consider protecting the cursor changes with a try-finally block so that problems in your processing don't leave the cursor in the wrong state:
if OpenDialog.Execute then begin
Screen.Cursor := crHourglass;
try
// TODO: something intensive
finally
Screen.Cursor := crDefault;
end;
end;
If the operation really uses a lot of time, consider moving it off to another thread. Then you don't have to worry about the GUI being unresponsive, and so you won't have to change the cursor in the first place.
I created an application with two forms. First one is the main form and second one is hidden.
I placed a button on Form1 and I made it ShowModal the second form. On Win7 the form appears with an animation. Then I close the appeared form (Form2) and I click the button once again. Form2 appears without the animation. I want the animation every time. What should I do?
The only thing I can think of right now is to create the form manually each time you want to display it modally. To do this, go to the project options and make sure that the form isn't automatically created. Then do
procedure TForm1.Button1Click(Sender: TObject);
begin
with TForm2.Create(self) do
try
ShowModal;
finally
Free;
end;
end;
In my opinion, most often modal forms should in fact be created manually.
Well, you could just elect not to worry about it! Alternatively a very quick hack would be to free the form each time it closes since the animation appears to run only on the first time the form is shown.
EDIT: Another approach would be to call DestroyHandle on your form whenever it closes. I'm guessing now, but I imagine that Windows records somewhere in the window a flag indicating that the animation has been shown. Once this flag has been set the animation is never shown again.
As an alternative way it's possible to fool windows by sending a notification that form's style has been changed, that will make windows reset "secret flag" for current form's handle. Thus, on showing already created form the cool show effect animation will be applied again. However, I can't say what negative effects can be caused by doing this way.
uses
Winapi.Windows, Vcl.Controls;
type
TFormHelper = class helper for TForm
public
procedure Show;
end;
implementation
procedure TFormHelper.Show;
begin
SendMessage(Handle,CM_CUSTOMSTYLECHANGED,0,0);
inherited Show;
end;
Note: code featured with a class helper, this feature/keyword might be not available in older IDEs.