Kernel

From TeamDeveloperWiki

Jump to: navigation, search

This page covers Windows Kernel tips & tricks.

Contents


Image:Pointer.pngHow 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 )


Image:Pointer.pngGet 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



Image:Pointer.pngOpen 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):



Image:Pointer.pngCreating 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:




Image:Pointer.pngHow 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

Image:Pointer.pngFormat 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):