2005 ...
januari februari maart april (1) mei juni (16) juli augustus september (12) oktober (14) november (8) december (3)
2005-06-08 19:36 i87 [permalink]
One type of 'application without forms', is using the {$APPTYPE CONSOLE}
setting to replace the default {$APPTYPE GUI}
. When using Write
and WriteLn
the output is sent to a command prompt box, either the one the application was started in, or a new one if the application is started from the graphical environment (GUI).
If no commant prompt window is needed, and all you need is your exe running, you really end up with an application without forms. If you open the project source (the .dpr file) from the menu: Project > View Source, or with Ctrl+F12, you will see these lines:
Application.Initialize;
Application.Run;
Application.Initialize
calls initialization some units require to be done right before the application starts, e.g. when using COM objects. Application.Run
loops until the application is terminated, and processes incoming windows messages. If you add forms or datamodules, Application.CreateForm
calls are added inbetween these two.
Sometimes, when using an application without forms, you get a button on the taskbar anyway. This is done every time Application.Handle
is used, e.g. when using Application.MessageBox
. If you don't want this, you might consider not using Application (if you don't include the Forms unit in the project the final exe-file could be much smaller!) but that might create a number of other problems. Another solution is this code, executed in the start-up code.
ShowWindow(Application.Handle,SW_HIDE);
By using the Handle property, the task-bar button is created, and by using the Windows function ShowWindow
you can hide this button without changing the internal states of the Application object.
This task-bar button actually has a seperate right-click menu only with options Restore, Minimize and Close, that tie in to the Application object, which is different to the default right-click menu (SystemMenu) that has Move and Resize also. To have a taskbar-button for each window, see the CreateParams trick.
Taskbar-button per form in an application
2005-06-08 20:41 i89 [permalink]
If you want each form in an application to have a taskbar-button of its own, you need to add this code somewhere between the private and public section of the class declaration of your TForm descendant type:
protected
procedure CreateParams(var Params: TCreateParams); override;
At the bottom add this (where Form1 is the name of your form):
procedure TForm1.CreateParams(var Params: TCreateParams);The virtual CreateParams procedure defined by the base TForm class, is used to modify the parameters used to call the Windows functions to do the work, before creating the window on screen. By setting the parent window to the desktop, a taskbar-button appears, with the icon and caption of the form. It also has the full default SystemMenu with all the options (according to the BorderIcons property of the form). The SystemMenu on the taskbar-button that is created by/for the Application object, is typically missing the Move and Size options.
begin
inherited;
Params.WndParent:=GetDesktopWindow;
end;
Application version: alternative to GetFileVersionInfo
2005-06-08 22:05 i93 [permalink]
GetFileVersionInfo can have trouble with your executable being locked. Normally it doesn't, but still, if you know when starting an application, all resources in the exe-file are loaded into memory, it makes no sense to re-read the exe-file to get to the version resource data.
There is a resource type RT_VERSION. A ready-made standard-Delphi object TResourceStream
provides access to the version data. VerQueryValue
can read this data for you. Strangely enough you need to copy the data for it to get accessable, I copy it to a TMemoryStream here:
uses Windows,Classes,SysUtils;
var
verblock:PVSFIXEDFILEINFO;
versionMS,versionLS:cardinal;
verlen:cardinal;
rs:TResourceStream;
m:TMemoryStream;
p:pointer;
s:cardinal;
begin
m:=TMemoryStream.Create;
rs:=TResourceStream.CreateFromID(HInstance,1,RT_VERSION);
m.CopyFrom(rs,rs.Size);
rs.Free;
m.Position:=0;
if VerQueryValue(m.Memory,'\',pointer(verblock),verlen) then
begin
VersionMS:=verblock.dwFileVersionMS;
VersionLS:=verblock.dwFileVersionLS;
AppVersionString:=Application.Title+' '+
IntToStr(versionMS shr 16)+'.'+
IntToStr(versionMS and $FFFF)+'.'+
IntToStr(VersionLS shr 16)+'.'+
IntToStr(VersionLS and $FFFF);
end;
if VerQueryValue(m.Memory,PChar('\\StringFileInfo\\'+IntToHex(GetThreadLocale,4)+IntToHex(GetACP,4)+'\\FileDescription'),p,s) or
VerQueryValue(m.Memory,'\\StringFileInfo\\081304E4\\FileDescription',p,s) or //nl-be?
VerQueryValue(m.Memory,'\\StringFileInfo\\040904E4\\FileDescription',p,s) then //en-us?
AppVersionString:=PChar(p)+' '+AppVersionString;
m.Free;
end;
The text info in the version resource data is stored per locale-id/codepage-id combination (I haven't seen any version data blocks with more than one of this combinations, but then again, I haven't seen that much binary data of versionresourcedatablocks) so there's the option of picking up the currently valid LCID, or have some default (nl-be in my case, $0813, and internationally default $0409 also). The Delphi Project Options dialog, version tab, has a locale selection, so if you're sure about which one you're using there, you might just use that one in a single VerQueryValue in the last if statement.
Application version: alternative to GetFileVersionInfo
2005-06-08 22:06 r48 [permalink]
→ Application version: alternative to GetFileVersionInfo
ExitWindowsEx and setting the privilige for it, yourself!
2005-06-08 22:11 i94 [permalink]
ExitWindowsEx
throws a privilege not set error by default, but there's a way to set this required privilege:
procedure RebootComputer;
var
th:THandle;
lid:Int64;
tp,tpx:TTokenPrivileges;
tpc:cardinal;
begin
if not(OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,th)) then
RaiseLastOSError;
if not(LookupPrivilegeValue('','SeShutdownPrivilege',lid)) then
RaiseLastOSError;
tp.PrivilegeCount:=1;
tp.Privileges[0].Luid:=lid;
tp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
tpc:=0;
if not(AdjustTokenPrivileges(th,false,tp,SizeOf(tp),tpx,tpc)) then
RaiseLastOSError;
if not(ExitWindowsEx(EWX_REBOOT,0)) then RaiseLastOSError;
end;
Answering to the WM_QUERYENDSESSION message
2005-06-08 22:16 i95 [permalink]
Check if the Messages
and Windows
units are included in the uses
clause in the start of your unit.
Add this bit to the protected
clause in the form class declaration. By default there is no need for a protected
clause, so if it's missing, type protected
at the same level of public
or private
.
procedure FormQueryEndSession(var Msg:TWMQueryEndSession); message WM_QUERYENDSESSION;
Declare the method something like this, adapt where neccessary to fit in your application.
procedure TMainWin.FormQueryEndSession(var Msg: TWMQueryEndSession);
begin
Msg.Result:=1;
PostMessage(Application.Handle,WM_CLOSE,0,0);
end;
We can't just call Close;
because this method is called from the message loop from your application (have a look at TApplication.Run
) and some things might need to happen after returning from this method. So we let Windows post us a close message so the internals of Application
can do the close the correct way (something like simulating an Alt+F4
).
If your application checks if the opened file has changed and needs to be saved, in the OnClose
event or equivalent (never write clean-up-code in the OnClick of a 'Close' button or menuitem!!), you can do Msg.Result:=0;
to let Windows know you're not ready to close and need the user to save the changes or press OK to discard the changes.
Enable dropping files onto your application
2005-06-08 22:18 i96 [permalink]
Check if the Messages
and ShellApi
units are included in the uses
clause in the start of your unit.
Add a call to DragAcceptFiles
in the initialization of the form (OnCreate
or OnShow
).
Add this bit to the protected
clause in the form class declaration. By default there is no need for a protected
clause, so if it's missing, type protected
at the same level of public
or private
.
procedure FormDropFiles(var Msg:TWMDropFiles); message WM_DROPFILES;
Declare the method something like this, adapt where neccessary to fit in your application.
procedure TMainWin.FormDropFiles(var Msg: TWMDropFiles);
var
i,FileCount,FileNameSize:integer;
FileName:string;
begin
FileCount:=DragQueryFile(Msg.Drop,-1,nil,0);
for i:=0 to FileCount-1 do
begin
FileNameSize:=DragQueryFile(Msg.Drop,i,nil,0)+1;
SetLength(FileName,FileNameSize);
DragQueryFile(Msg.Drop,i,@FileName[1],FileNameSize);
//skip closing #0 char
SetLength(FileName,FileNameSize-1);
//do something with FileName here...
end;
DragFinish(Msg.Drop);
end;
If you only need one file, you can skip the for loop and just use DragQueryFile(Msg.Drop,0,,);
2005-06-10 20:45 i107 [permalink]
C4, short for Connect 4. The first version was a school project to employ all available techniques of artificial intelligence that applies to the algorhythm, to calculate the next best move. This version has updated graphics, a timer, and an attempt to show some internal numbers to help in competition training. This version also has a game-state load/save feature.
2005-06-10 20:46 freeware [permalink]
Here are a few applications I wrote, a few of them I use myself, a few were just for fun...
They're put public here as FreeWare, some are OpenSource. I haven't figured out yet if I need to put them here under a license or even which one. So for now they're all rights reserved and use em at your risk, though there's really nothing to fear because they really don't do more then they're supposed to do.
Anyway, if you really want to have a look at the SourceCode, let me know -- StijnSanders
(Click on these icons:)
AllSorts (shell extension)
Growthris
IconSuite
WikiEngine
TortoiseSVN icons
xxm
→github.com/stijnsanders
2005-06-10 20:48 barcode [permalink]
This is a little idea I had (after I had to do something similar at work, off course), and I built up into a test-utility to compare BarCode''''s with.
I noticed Delphi has a TBits object, it's a sort of TList, but only stores a list of bits (exposed as booleans). Really handy to store an encoded string of characters, and to start from to do something with it, e.g. generate a TBitmap, or HTML code, or anything really...
Have a look at the tester-utility (barcodestuff_exe.zip ~218KB) or the Delphi7 source (barcodestuff_src.zip ~14KB). It's really basic, not calculating CheckSum digits, and doing only basic checks on which strings it gets.
CodaBar, Code11, Code39, Code93, Code128, Interleaved2of5, UPC/EAN
2005-06-10 20:50 i110 [permalink]
Growthris is a crazy Tetris with a twist. Not only is the gamespace vertically cyclic, it is expanding! But not the view! Keep track of what's where with a limited view, while downward motion of the bricks is speeding up!
2005-06-10 20:51 i111 [permalink]
MailCount might come in handy if you want to follow the continuous flow of mail in your inbox, but don't want to have Outlook open all of the time.
This application still needs Outlook though, so you best have Outlook minimized. If you don't have Outlook open, ActiveX will start it in the background.
If there is a "MailCount.wav
" file present in the directory where you save this exe, it will be played whenever the count of unread mails increases.
If your 'unread mail count' rises above 100, the number divided by 10 is shown in blue.
In the zip is also a version that connects to POP3: PopCount.exe. When run the first time, it shows "00" in red, indicating an error. Double click to enter the POP3 login data. Your password is saved encrypted in the PopCount.ini file.
2005-06-10 20:52 i112 [permalink]
dsCt_1.exe, is a self-extracting RAR that extracts the files to a Program Files directory, and starts the Microsoft register server. On some older windows versions, this call fails, and you have to register the OCX yourself.
Together with the main OCX, a directory with documentation html is provided, that uses the dsWebTreeView for navigation itself.
Use the OCX and the documentation to have a TreeView contol on your web-page. See the HTML source of the documentation for an example. (Or this site! example)
2005-06-10 20:53 odo [permalink]
Odo began as an attempt to write my own odometer, a counter of how much distance you travel with the mouse-cursor on screen. Since this kind of data takes some time to collect, I was more interested in when I did how much with the mouse. Later I added a keystroke-counter and a link to a local database, to be able to look up my history of activity.
As of version 0.4, the data link uses sqlite3.dll: odo_511.zip 646KB,
Keep using version 0.3 to use a data link based on OLEDB/ADO: odo_278.zip 338KB
The graph displays the measured values with a combination of colors, at one minute per horizontal pixel:
Upper graph:
Green: Horzontal mouse movement
Red: Vertical mouse movement
Lower graph:
Green: Keystrokes
Red: Mouseclicks
Blue: Application switches
Since these are the basic colors, overlapping dispay results in different colors: red and green make yellow, blue and green make light-blue (cyan), blue and red make purple (magenta), and all three make white.
2005-06-10 20:54 re [permalink]
RE, short for Regular Expression is a tool to build advanced structures that use, among other things, Regular Expressions to transform text. I didn't spend too much time thinking about a decent name for the application and a first version only operated on the clipboard (and was called CBRE: Clipboard Regular Expression), so I got stuck with 'Regular Expression'. Another rule I broke is that you can't really operate it with the keyboard only. In return there is a really nifty drag-and-drop way of moving items around and connecting them, really a nice way to visualise the structure you're working on, and easy to have more items than needed around when building or debugging.
Starter's guide:
» Download and install RE_setup.exe (~1.8MB), and have the wizard start RE. Hit the 'Register Regular Expression data file type' button on the settings dialogs. This registers the .rxe file format with Windows to open the files easily.
» The application starts with an empty workspace, use the Add menu on the main-menu, or use the right-click menu in the workspace that has all the items also. Pick an item, e.g. Input/Output > Clipboard, and another, e.g. Input/Output > Viewer. Now drag from one of the sunken rectagles, called linkpoints, to the other to establish a link. If you now hit Run, the text-contents of the clipboard, if any, are shown in the Viewer.
» To move bigger structures around, drag on the open workspace, to get a running ants rectangle to select multiple items. When a structure is bigger than your screen and you need to scroll, hold Ctrl down and drag the workspace around.
Update 2014-01-01: This project is now open-source! https://github.com/stijnsanders/RE
RE_setup.exe (~1.8MB)
2005-06-10 20:55 i115 [permalink]
TreeBrowse (~585KB) was a small project at first to have something better than a one-dimensional browse history (back, forward). By building a tree-structure as you browse through pages (and surf the web), you have a better view of how you got to where you are.
And there's more. On summary pages with links, you see a number of things you want to read, but when done with the first, you can't find the other any more. Press the links whil holding Ctrl, and nodes are added to the tree for later. Then view the items at you own pace. To clarify the overview, mark nodes with different icons, or drag and drop them to other places in the tree.
http://yoy.be/freeware/TB_setup.exe