Kernel
From TeamDeveloperWiki
This page covers Windows Kernel tips & tricks.
How to suspend an application for a specific interval
There have been reports the SalPause function creates instability in some TD versions.
Use the WinApi function Sleep instead.
This is the declaration
Library name: KERNEL32.DLL
Function: Sleep
Export Ordinal: 0
Returns
Parameters
Number: DWORD
The interval is set to milliseconds (1000 = 1 second)
! Suspend the application for 5 seconds Call Sleep( 5000 )
Get the time which has elapsed since the system was started
Use the WinApi function GetTickCount.
This is the declaration
Library name: KERNEL32.DLL
Function: GetTickCount
Export Ordinal: 0
Returns
Parameters
Number: DWORD
It returns the time in milliseconds.
You can use this function to measure the duration of specific parts in your application
Set nStartTime = GetTickCount( ) ! ! Here specific code to measure its performance Call ExecuteAVeryHeavyFunction( ) ! Set nEndTime = GetTickCount( ) ! ! Now calculate the measured time in milliseconds Set nExecutionTime = nEndTime - nStartTime
Open an empty email in the default email client
Here an easy way to open an empty email using your default email client (eg Outlook) and having filled in the fields
for "mailto", "CC", "BCC", "Subject" and body.
Use the WinApi function ShellExecuteA.
This is the declaration
Library name: SHELL32.DLL
Function: ShellExecuteA
Export Ordinal: 0
Returns
Parameters
Window Handle: HWND
String: LPCSTR
String: LPCSTR
String: LPCSTR
String: LPCSTR
Number: INT
Use the "Open" command for "Mailto:".
Below a sample
Set sMailTo = "mailto:John.Doe@somewhere.com" Set sCC = "cc=info@somewhere.com" Set sBCC = "bcc=info2@there.com" Set sSubject= "subject=Request for some info" Set sBody = "body=Here my request for some info. Best regards" ! Set sEmail = sMailTo || "?" || sCC || "&" || sBCC || "&" ||sSubject || "&" ||sBody ! ! Call ShellExecuteA( hWndForm, "open", sEmail, STRING_Null, STRING_Null, 1 ) !
Beware that the email will be only text based. No formatting is possible or adding HTML tags.
When you need a newline or TAB in the body text, use the next codes
Newline -> %0D%0A Tab -> %09
So if you want a newline in the bodytext of the sample above
Set sBody = "body=Here my request for some info.%0D%0ABest regards"
Here you can download a sample (created with TD 5.1, using the UNICODE function ShellExecuteW):
Creating process tree using ToolHelp32 to get parent and child processes
Using Toolhelp32 API, you can create a snapshot of all current running processes in the system.
Such a snapshot holds the tree of processes, where information of the processes and their relationships are gathered.
For instance, it holds which process is the parent of another process and which descendants (child) processes it started.
Having this information you are able to determine which process started your application. For instance if your app is started from a batch or is running as a service or was started from another TD application. You can also determine which processes are started from your app. For instance Internet Explorer, or another TD application.
By traversing the snapshot (linking the parent/child relationships) you are able to create a tree of processes. Just like [ProcessExplorer] does.
ToolHelp32 is part of Kernel32.dll and to get a process snapshot these API functions are used:
- CreateToolhelp32Snapshot : Takes a snapshot of the specified processes
- Process32First : Retrieves information about the first process encountered in a system snapshot.
- Process32Next : Retrieves information about the next process recorded in a system snapshot.
The first and next functions retrieve a PROCESSENTRY32 structure describing an entry from a list of the processes residing in the system address space when a snapshot was taken.
It contains process information such as the name of the executable file, the process identifier, and the process identifier of the parent process.
A ready to go implementation can be downloaded from the Sample Vault.
It contains a library with needed classes to create a snapshot.
The main application shows an outlinelistbox with the tree of processes. The red colored process is the current process.
Here you can download a sample:
How to set the value of environment variables
Using the WinAPI functions SetEnvironmentVariableA (ANSI) and SetEnvironmentVariableW (UNICODE)
you can set and delete environment variables in the current process.
These are the declarations (both ANSI and UNICODE)
Library name: KERNEL32.DLL
Function: SetEnvironmentVariableA
Export Ordinal: 0
Returns
Boolean: BOOL
Parameters
String: LPCSTR
String: LPCSTR
Function: SetEnvironmentVariableW
Export Ordinal: 0
Returns
Boolean: BOOL
Parameters
String: LPWSTR
String: LPWSTR
And here a sample how to set the PATH variable
Set bOk = SetEnvironmentVariableA( "PATH", "C:\\TEST" )
Be aware that if you set a environment variable from within your application, the value is only available in the current process and
in the child processes started from your TD application. When the application ends, the set variables are back to their initial values.
So using this function, you are unable to set the overall variable values for all other applications.
A nice usage of this is setting the PATH variable at startup of your application to the needed paths which then are only known by the current running application. The PATH setting will be reverted back when the application ends, which does drop the need to set global environment variables for your complete system.
Here you can download a sample:
To get the variable value, See How to get the value of environment variables
Format date and time using GetDateFormat and GetTimeFormat
One drawback of function SalFmtFormatDateTime is that you cannot format a date(time) using a specific locale (language).
Also the Sal function has a limited set of formats to be used.
You can also use the WinApi functions GetDateFormat and GetTimeFormat.
Based on the default (user or system) locale you can get the names of days and months in the specific language.
For example, here some LONGDATE formatted strings in their locales:
Dutch maandag 23 november 2009 French lundi 23 novembre 2009 English Monday, November 23, 2009 German Montag, 23. November 2009 Spanish lunes, 23 de noviembre de 2009
You can find the specific locale ID's to be used here:
Below the possible format options for date and time
d Day of the month as digits without leading zeros for single-digit days. dd Day of the month as digits with leading zeros for single-digit days. ddd Abbreviated day of the week as specified by a LOCALE_SABBREVDAYNAME* value dddd Day of the week as specified by a LOCALE_SDAYNAME* value. M Month as digits without leading zeros for single-digit months. MM Month as digits with leading zeros for single-digit months. MMM Abbreviated month as specified by a LOCALE_SABBREVMONTHNAME* value MMMM Month as specified by a LOCALE_SMONTHNAME* value y Year represented only by the last digit. yy Year represented only by the last two digits. A leading zero is added for single-digit years. yyyy Year represented by a full four or five digits, depending on the calendar used. yyyyy Behaves identically to "yyyy". g, gg Period/era string formatted as specified by the CAL_SERASTRING value. h Hours with no leading zero for single-digit hours; 12-hour clock hh Hours with leading zero for single-digit hours; 12-hour clock H Hours with no leading zero for single-digit hours; 24-hour clock HH Hours with leading zero for single-digit hours; 24-hour clock m Minutes with no leading zero for single-digit minutes mm Minutes with leading zero for single-digit minutes s Seconds with no leading zero for single-digit seconds ss Seconds with leading zero for single-digit seconds t One character time marker string, such as A or P tt Multi-character time marker string, such as AM or PM
It is also possible to mix text along with the available formats.
Example
sFormat = "'This is day' dd 'of month' MM '(' MMMM ')'"
Output = "This is day 23 of month 11 ( November )"
Here you can download a sample (both ANSI and UNICODE versions):

