Greetings: ni hao nee how
Thank you: Xie xie ni sheh sheh nee
your welcome: bu xie boo sheh
Hello, my name is Joe: Ni hao, wo shi joe or Ni hao, wo jaio joe nee how, wah shih joe OR nee how, wah jow joe ("jow" uses same "o" sound as "owl")
Where is the Water Closet (toliet): Ce suo zai nar chuh saw zie nar
Do you understand: Ni dong ma? or Ni dong bu dong? nee dong ma ("dong" uses a long "o" as in the word "owner") or nee dong boo dong
Questions are formulated with questions words like what, how or ends with the Ma or ba character Or choice type as in understand no understand like the sentence above dong by dong, the answer would be either understand or no understand.
I: Wo wah ("a" sound as in "wall")
You: Ni nee
He/She: ta tah
Us: Wo men wah mun
They: Ta men tah mun ("tah" as in the word "taught")
You guys: Ni men nee mun
Who: Shei shay
What: Shen me shun muh
when: shen me shi hao shun muh shih how
where: Nar or Na Li nar, or nah lee
why: wei shen me way shun muh
how: zen me yang zen muh yang (the "a" in "yang" sounds like the "a" in "water")
this: zhe juh
that: na nah
here: zhe li juh lee
there: na li nah lee
If: ru gou rue gah ("gah" uses same "a" sound as "father")
but: dan shi don shih
because: yin wei yin way
yes / is(to be: shi shih
no: bu boo
Please: Qing ching
What did you say: Ni shuo shen me nee shaw shun muh
Assist me for a sec: Bang wo yi xia bong wah ee shah
How much: Duo shao (how many) dah show ("show" rhymes with the word "ow")
I'll Buy it: wo yao mai wah yow mie ("yow" rhymes with "ow")
I wont buy it: Wo bu yao mai or bu xiang mai wah boo yow mie, or, boo shahng mie
Too expensive: tai gui le tie gway luh
II) Chatting
Whats your surname: Ni gui xing nee gway shing
Whats your name: Ni jiao shen me ming zi nee jow (rhymes with "ow") shun muh ming jih
How are you? also greetings: Ni hao ma? nee how mah
I'm fine: Wo hao wah how
I'm not good: Wo bu hao wah boo how
my chinese is bad: Wo de han yu bu hao or wo de zhong wen bu hao wah duh han ("a" as in "father") you boo how, or, wah duh joong ("oo" as in "foot") won boo how
Please speak english: Qing jiang ying wen ching jahng ying wun
Please speak slower: Qing jiang man yi diar ching jahng mahn ee dee are
What do you do (job: Ni zuo shen me gong zuo nee zau (as in "author") shun muh goong (as in "foot") zau
Whats your age: Ni ji sui? nee gee (as in "gee whiz") sway
Whats your hobby: Ni you shen me ai hao? nee yow shun muh I how
NOTE: Phonetics are in red
May 30, 2008
May 19, 2008
May 5, 2008
How to create Personal File Folders (.PST)
This guide will help you successfully create a .PST file which will contain Emails you wish to backup
- You need to create the file first. To do this, go to File --->New ---> Outlook Data File.
- Select Office Outlook Personal Folders File (.pst) and click OK
- Select a name for this folder. The default name is Personal Folders.pst, but you can use any name you want. For example, if you were trying to back up all your emails from December 2005, you could name the folder DEC2005.pst
- To make finding the file easier, you can save the file in your My Documents. The screenshot below shows this, but you can save it wherever you want.
- Type in the name of the folder in the Name field and click OK
- After completing the last step, it should have created a new folder in your "All Mail Folders" where your current mail folders are located.
- Locate this folder, it will be named whatever name you gave it in the last step. (We used "Personal Folders" )
- If you would like to rename the Personal Folder, you can simply right click the personal folder and select Properties. Here you will see the "Personal Folder Properties", click the "Advanced..." button on the bottom right. You should see a window that looks remarkably similar to the "Create Microsoft Personal Folder" image. Select the Name: field and change it to whatever name you would like.
- To save messages in this folder, simply drag emails into this folder.
- When you have completed moving messages into this folder, and would like to hide the folder, right click on the folder and select "Close..."
- If you would like to reopen a closed folder, click on File --->Open --->Outlook Data File
- Locate the file and click OK
- It should have put the folder back in your "All Mail Folders"
Mar 3, 2008
Using variables in sed
Question:How to use a variable from the OS in sed?
Example:
$VAR=`Smart keshav`
sed -e 's/keshav/$VAR/g' > filename
Solution:Use double quotes around the sed script rather than single quotes
Example:
sed -e "s/keshav/$VAR/g" > filename
Example:
$VAR=`Smart keshav`
sed -e 's/keshav/$VAR/g' > filename
Solution:Use double quotes around the sed script rather than single quotes
Example:
sed -e "s/keshav/$VAR/g" > filename
Mar 1, 2008
Matching Patterns
pattern: example: matches: not matched:
------------------------------------------------------------------
* boo* boot,boo,booth
? boo? boot booth
[...] [aeiou]* ark bark
[!...] boo[!st] boor boot
*(cccc) boo*(zer) boo,boor,booze,boozer boot
+(cccc) boo+(zer) boor,booze,boozer boo
?(cccc) boo?(zer) boo,boor,booze boozer
@(cccc) boo@(zer) booze,booth boo
!(cccc) boo!(zer) booth,boo,boot booze,boor
{c,c,c} a{b,c,d}e abe,ace,ade axe
Conditional Statements
format "true" if:
---------------------------------------------------
(( _num1_ == _num2_ )) numbers equal
(( _num1_ != _num2_ )) numbers not equal
(( _num1_ <> _num2_ )) num1 > num2
(( _num1_ <= _num2_ )) num1 <= num2
(( _num1_ >= _num2_ )) num1 >= num2
[[ _str1_ == _str2_ ]] strings equal
[[ _str1_ != _str2_ ]] strings not equal
[[ _str1_ <> _str2_ ]] str1 follow str2
[[ _str1_ = _pattern_ ]] str1 = pattern
[[ _str1_ != _pattern_ ]] str1 != pattern
[[ -z _str_ ]] str is null
[[ -n _str_ ]] str is not null
[ x=y -o k=j ] or in expression
[ x=y -a k=j ] and in expression
Test Objects (Files, Directories, etc.)
test "true" if: ksh
-----------------------------------
object exist -a
readable -r
writable -w
executable -x
non-zero length -s
zero length
directory -d
plain file -f
symbolic link -h
named pipe -p
block special file -b
character special file -c
soft link -L
socket -S
owned by me -O
owned by my group not
"sticky" bit set -k
set-group-ID bit set -g
set-user-id bit set -u
opened on a terminal not
Format of flow control functions
"if-then" if _expr_ then
_cmd(s)_
elif _expr_
_cmd(s)_
else
_cmd(s)_
fi
"case" case _word_ in
_pattern1_) _cmd(s)_
_pattern2_) _cmd(s)_
*) break ;;
esac
"while" while _expr_ do
_cmd(s)_
done
"for" for _variable_ in _list_
_cmd(s)_
done
"until" until _expr_
do
_cmd(s)_
done
POSITIONAL PARAMETER
program, function or shell $0
argument 1 through 9 $1 .. $9
nth argument ${n}
number of positional parameters $#
every positional parameter $@, $*
decimal value returned by last executed cmd $?
pid of shell $$
pid of last backgrounded command $!
REDIRECTIONS
0 stdin
1 stdout
2 stderr
<&- close stdin
>&- close stdout
<>filename open filename for read-write
2>&1 open 2 for write and dup as 1
Examples:
cmd 2>/dev/null
cmd >/dev/null 2>&1
exec 1<&- # close descriptor 1 exec 2<&-
# close descriptor 2 exec 1< /dev/null
# open descriptor 1 exec 2< /dev/null
# open descriptor 2
OTHER FUNCTIONALITIES
cmd1 cmd2 exec cmd2 if cmd1 fail
cmd1 && cmd2 exec cmd2 if cmd1 is OK
V1=${V2:=V3} Set V1 with the value of V2 if this is set else set the
variable V1 with value of V3 (V3 could be a number).
sh replacement: if [ $V2 ] ; then
V1=$V2
else
V1=$V3
Example: DisplaySize=${LINES:24} ; Command=${Command:"cat"}
${V1:?word} if V1 set & V1!=null ret $V1 else print word and exit
: ${V1:?"variable V1 not set on null"}
${V1:=word} if V1 !set V1==null set V1=$word
${V1:-word} if V1 set & V1!=null ret $V1 else ret word
${V1:+word} if V1 set & V1!=null ret word else ret nothing
${V1##patt}
${V1#patt} if patt are found at the begin of V1 return V1 whitout the patt
else return V1
V1="lspwd" ; ${V1#"ls"} # exec pwd
${V1%%patt}
${V1%patt} if patt are found at the end of V1 return V1 whitout the patt
else return V1
V1="lspwd" ; ${V1%"pwd"} # exec ls
COPROCESS
La ksh permette di lanciare uno o piu' comandi come processi in background.
Questi processi sono chiamati coprocesses e sono utilizzati per comunicare
con un programma.
Un coprocess si crea mettendo l'operatore & (pipe, ampersand) dopo un commando.
Entrambi stdin e stdout del commando sono piped verso il tuo script.
Un coprocess deve incontrare le seguenti restrizioni:
· Includi un new-line alla fine di ogni messaggio
· Manda ogni messaggio di output allo standard output
· Pulisce il suo stdout dopo ogni messaggio
L' esempio dimostra come l'input e' passato verso e ritornato da un coprocess:
echo "Initial process"
./FileB.sh &
read -p a b c d
echo "Read from coprocess: $a $b $c $d"
print -p "Passed to the coprocess"
read -p a b c d
echo "Passed back from coprocess: $a $b $c $d"
FileB.sh
echo "The coprocess is running"
read a b c d
echo $a $b $c $d
L'output risultante e' il seguente:
Initial process
Read from coprocess: The coprocess is running
Passed back from coprocess: Passed to the coprocess
Il comando 'print -p' ti permette discrivere verso il coprocess.
Per leggere dal coprocess, lancia il comando 'read -p'.
EXAMPLES
- Explode a command for use parameters counter
set `who -r` ; [ "$8" != "0" ] && exit
- declare a variable for only uppercase/lovercase chars
typeset -u VAR ; VAR="lower" ; echo $VAR -> LOWER
typeset -l VAR ; VAR="UPPER" ; echo $VAR -> upper
- exec
- eval - esegue il comando dato come argomento
- let - esegue le operazioni matematiche che passate come argomento
let "x = x * 5"
((x = x * 5)) .. altra forma di let
REGULAR EXPRESSION
- ritorna la prima lettera dopo il segno - all'inizio di una stringa
VAR="-ciao"
RESULT=`expr "$VAR" : "-\(.\)"`
echo $RESULT .. -c
- toglie il '-' iniziale
VAR="-ciao"
VAR=`expr "$VAR" : "-*\(.*\)"`
echo $VAR .. ciao
- ritorna la lunghezza di una stringa
VAR="ciao"
echo `expr length $SHELL` .. 4
- ritorna l'indice di dove incontra una substringa
echo `expr index abcdef de` .. 4
- ritorna 6 caratteri a partire dall'11
expr substr "Goodnight Ladies" 11 6 .. Ladies
ARRAY
- definisce un array
set -A Week Sat Sun Mon Tue Wed Thu Fri
- ritorna un elemento dell'array
echo ${Week[3]} .. Tue
id=3 ; echo ${Week[id]} .. Tue
- stampa tutti gli elemti di un array
echo ${Week[@]} .. Sat Sun Mon Tue Wed Thu Fri
- scandisce un array
for day in ${Week[@]}
do
echo $day
done
- ritorna il numero di elementi in un array
nelem=${#Week[@]} ; echo $nelem .. 7
Feb 7, 2008
Insert headers and footers in Word Documents
Create the same header or footer for each page
On the View menu, click Header and Footer to open the header or footer (header and footer: A header, which can consist of text or graphics, appears at the top of every page in a section. A footer appears at the bottom of every page. Headers and footers often contain page numbers, chapter titles, dates, and author names.) area on a page.
To create a header, enter text or graphics in the header area.
To create a footer, click Switch Between Header and Footer on the Header and Footer toolbar (toolbar: A bar with buttons and options that you use to carry out commands. To display a toolbar, press ALT and then SHIFT+F10.) to move to the footer area, and then enter text or graphics.
If necessary, format text by using buttons on the Formatting toolbar.
When you finish, click Close on the Header and Footer toolbar.
Tips
The text or graphic you enter in a header or footer is automatically left aligned. You may want to center the item instead or include multiple items (for example, a left-aligned date and a right-aligned page number). To center an item, press TAB; to right align an item, press TAB twice.
You can also use buttons on the Header and Footer toolbar to enter text into the header and footer area.
Create a different first page header or footer
You can leave the header or footer (header and footer: A header, which can consist of text or graphics, appears at the top of every page in a section. A footer appears at the bottom of every page. Headers and footers often contain page numbers, chapter titles, dates, and author names.) off the first page or create a unique first page header or footer for the first page in a document or the first page of each section within a document.
If your document is divided into sections (section: A portion of a document in which you set certain page formatting options. You create a new section when you want to change such properties as line numbering, number of columns, or headers and footers.), click in a section or select multiple sections you want to change. Click anywhere if your document is not divided into sections.
On the View menu, click Header and Footer.
On the Header and Footer toolbar (toolbar: A bar with buttons and options that you use to carry out commands. To display a toolbar, press ALT and then SHIFT+F10.), click Page Setup .
Click the Layout tab.
Select the Different first page check box, and then click OK.
If necessary, click Show Previous or Show Next on the Header and Footer toolbar to move into the First Page Header area or First Page Footer area.
Create the header or footer for the first page of the document or section.
If you don't want a header or footer on the first page, leave the header and footer areas blank.
To move to the header or footer for the rest of the document or section, click Show Next on the Header and Footer toolbar. Then create the header or footer you want.
Create different headers or footers for odd and even pages
On the View menu, click Header and Footer.
On the Header and Footer toolbar (toolbar: A bar with buttons and options that you use to carry out commands. To display a toolbar, press ALT and then SHIFT+F10.), click Page Setup .
Click the Layout tab.
Select the Different odd and even check box, and then click OK.
If necessary, click Show Previous or Show Next on the Header and Footer toolbar to move into the odd or even header or footer (header and footer: A header, which can consist of text or graphics, appears at the top of every page in a section. A footer appears at the bottom of every page. Headers and footers often contain page numbers, chapter titles, dates, and author names.) areas.
Create the header or footer for odd-numbered pages in the Odd Page Header or Odd Page Footer area and create the header or footer for even-numbered pages in the Even Page Header or Even Page Footer area.
Create a different header or footer for part of a document
A document must first be divided into sections (section: A portion of a document in which you set certain page formatting options. You create a new section when you want to change such properties as line numbering, number of columns, or headers and footers.) in order to create a different header or footer (header and footer: A header, which can consist of text or graphics, appears at the top of every page in a section. A footer appears at the bottom of every page. Headers and footers often contain page numbers, chapter titles, dates, and author names.) for part of a document.
If you haven't done so already, insert a section break (section break: A mark you insert to show the end of a section. A section break stores the section formatting elements, such as the margins, page orientation, headers and footers, and sequence of page numbers.) where you want to start a new section that contains a different header or footer.
How?
Click where you want to insert a section break (section break: A mark you insert to show the end of a section. A section break stores the section formatting elements, such as the margins, page orientation, headers and footers, and sequence of page numbers.).
On the Insert menu, click Break.
Under Section break types, click the option that describes where you want the new section (section: A portion of a document in which you set certain page formatting options. You create a new section when you want to change such properties as line numbering, number of columns, or headers and footers.) to begin.
Click in the section for which you want to create a different header or footer.
On the View menu, click Header and Footer.
On the Header and Footer toolbar (toolbar: A bar with buttons and options that you use to carry out commands. To display a toolbar, press ALT and then SHIFT+F10.), click Link to Previous to break the connection between the header and footer in the current section and the previous section.
Microsoft Word no longer displays "Same as Previous" in the upper-right corner of the header or footer.
Change the existing header or footer, or create a new one for this section.
Source: http://office.microsoft.com/en-us/word/HP051863231033.aspx
On the View menu, click Header and Footer to open the header or footer (header and footer: A header, which can consist of text or graphics, appears at the top of every page in a section. A footer appears at the bottom of every page. Headers and footers often contain page numbers, chapter titles, dates, and author names.) area on a page.
To create a header, enter text or graphics in the header area.
To create a footer, click Switch Between Header and Footer on the Header and Footer toolbar (toolbar: A bar with buttons and options that you use to carry out commands. To display a toolbar, press ALT and then SHIFT+F10.) to move to the footer area, and then enter text or graphics.
If necessary, format text by using buttons on the Formatting toolbar.
When you finish, click Close on the Header and Footer toolbar.
Tips
The text or graphic you enter in a header or footer is automatically left aligned. You may want to center the item instead or include multiple items (for example, a left-aligned date and a right-aligned page number). To center an item, press TAB; to right align an item, press TAB twice.
You can also use buttons on the Header and Footer toolbar to enter text into the header and footer area.
Create a different first page header or footer
You can leave the header or footer (header and footer: A header, which can consist of text or graphics, appears at the top of every page in a section. A footer appears at the bottom of every page. Headers and footers often contain page numbers, chapter titles, dates, and author names.) off the first page or create a unique first page header or footer for the first page in a document or the first page of each section within a document.
If your document is divided into sections (section: A portion of a document in which you set certain page formatting options. You create a new section when you want to change such properties as line numbering, number of columns, or headers and footers.), click in a section or select multiple sections you want to change. Click anywhere if your document is not divided into sections.
On the View menu, click Header and Footer.
On the Header and Footer toolbar (toolbar: A bar with buttons and options that you use to carry out commands. To display a toolbar, press ALT and then SHIFT+F10.), click Page Setup .
Click the Layout tab.
Select the Different first page check box, and then click OK.
If necessary, click Show Previous or Show Next on the Header and Footer toolbar to move into the First Page Header area or First Page Footer area.
Create the header or footer for the first page of the document or section.
If you don't want a header or footer on the first page, leave the header and footer areas blank.
To move to the header or footer for the rest of the document or section, click Show Next on the Header and Footer toolbar. Then create the header or footer you want.
Create different headers or footers for odd and even pages
On the View menu, click Header and Footer.
On the Header and Footer toolbar (toolbar: A bar with buttons and options that you use to carry out commands. To display a toolbar, press ALT and then SHIFT+F10.), click Page Setup .
Click the Layout tab.
Select the Different odd and even check box, and then click OK.
If necessary, click Show Previous or Show Next on the Header and Footer toolbar to move into the odd or even header or footer (header and footer: A header, which can consist of text or graphics, appears at the top of every page in a section. A footer appears at the bottom of every page. Headers and footers often contain page numbers, chapter titles, dates, and author names.) areas.
Create the header or footer for odd-numbered pages in the Odd Page Header or Odd Page Footer area and create the header or footer for even-numbered pages in the Even Page Header or Even Page Footer area.
Create a different header or footer for part of a document
A document must first be divided into sections (section: A portion of a document in which you set certain page formatting options. You create a new section when you want to change such properties as line numbering, number of columns, or headers and footers.) in order to create a different header or footer (header and footer: A header, which can consist of text or graphics, appears at the top of every page in a section. A footer appears at the bottom of every page. Headers and footers often contain page numbers, chapter titles, dates, and author names.) for part of a document.
If you haven't done so already, insert a section break (section break: A mark you insert to show the end of a section. A section break stores the section formatting elements, such as the margins, page orientation, headers and footers, and sequence of page numbers.) where you want to start a new section that contains a different header or footer.
How?
Click where you want to insert a section break (section break: A mark you insert to show the end of a section. A section break stores the section formatting elements, such as the margins, page orientation, headers and footers, and sequence of page numbers.).
On the Insert menu, click Break.
Under Section break types, click the option that describes where you want the new section (section: A portion of a document in which you set certain page formatting options. You create a new section when you want to change such properties as line numbering, number of columns, or headers and footers.) to begin.
Click in the section for which you want to create a different header or footer.
On the View menu, click Header and Footer.
On the Header and Footer toolbar (toolbar: A bar with buttons and options that you use to carry out commands. To display a toolbar, press ALT and then SHIFT+F10.), click Link to Previous to break the connection between the header and footer in the current section and the previous section.
Microsoft Word no longer displays "Same as Previous" in the upper-right corner of the header or footer.
Change the existing header or footer, or create a new one for this section.
Source: http://office.microsoft.com/en-us/word/HP051863231033.aspx
Jan 4, 2008
How to Add Items to the "Send To" Menu in Windows XP
1. Click Start, and then click Run.
2. In the Open box, type sendto, and then click OK.
3. Add a destination by doing one of the following:
Use the drag-and-drop operation to move the item that you want to the SendTo folder; to do so, right-click, and then click Create Shortcuts Here.
-or-
Point to New on the File menu, and then click Shortcut. Follow the instructions in the Create Shortcut Wizard. A new shortcut is created in the SendTo folder, and it is displayed on the Send To menu.
2. In the Open box, type sendto, and then click OK.
3. Add a destination by doing one of the following:
Use the drag-and-drop operation to move the item that you want to the SendTo folder; to do so, right-click, and then click Create Shortcuts Here.
-or-
Point to New on the File menu, and then click Shortcut. Follow the instructions in the Create Shortcut Wizard. A new shortcut is created in the SendTo folder, and it is displayed on the Send To menu.
Oct 29, 2007
Find Complete line NOT matched by the regular expression
Some times it’s required get all the instances which are not in the match string.
For example consider the following string.
I think that Michel Smith
is a fictional character. His real name
might be Michel Jackson, Michel Westling,
or Michel Liu for all we know.
If we are interested to get all lines which does not consist of word “Michel”, we can use Regex in .net and create a regular expression as follows
“^(?:(?!(.*Michel.*)).)*$\r?\n?”
i.e. ResultString = Regex.Match(strTest, "^(?:(?!Michel).)*$\r?\n?",RegexOptions.Multiline).Value
strTest contains the Test string.
and the job is done.
Happy coding…
For example consider the following string.
I think that Michel Smith
is a fictional character. His real name
might be Michel Jackson, Michel Westling,
or Michel Liu for all we know.
If we are interested to get all lines which does not consist of word “Michel”, we can use Regex in .net and create a regular expression as follows
“^(?:(?!(.*Michel.*)).)*$\r?\n?”
i.e. ResultString = Regex.Match(strTest, "^(?:(?!Michel).)*$\r?\n?",RegexOptions.Multiline).Value
strTest contains the Test string.
and the job is done.
Happy coding…
Oct 3, 2007
TRY! MAGIC
#1 *An Indian discovered that nobody can create a FOLDER anywhere on the Computer which can be named as "CON". This is something pretty Cool...and Unbelievable. ... At Microsoft the whole Team, couldn't answer why this happened ! TRY IT NOW ,IT WILL NOT CREATE " CON " FOLDER **MAGIC
#2 * *For those of you using Windows, do the following: *1.) Open an empty notepad file 2.) Type "Bush hid the facts" (without the quotes) *3 *.) Save it as whatever you want. 4.) Close it, and re-open it. *MAGIC
#3 *Open Microsoft Word and type =rand (200, 99) And then press ENTER Then see the magic...
This can help to understand why
1.Device names such as COM1, CON or LPT1 are reserved words, and they can't be used as folder or file names.
2. The reasons why notepad is not able to display any combination of string if the text contains the words with 4 3 3 5 number of letters..
Finally found out that its not a bug with notepad..
What happens is..
Whenever we open a text file in notepad, it determines whether the text is ASCII or Unicode.. But actually there is no way in the world to exactly determine whether the text is ASCII or Unicode.. There is a function called IsTextUnicode in windows API.. The function does some tests on the text based on statistical data.. This is what MSDN says about the function.."The function uses various statistical and deterministic methods to make its determination.. These tests are not foolproof. The statistical tests assume certain amounts of variation between low and high bytes in a string, and some ASCII strings can slip through. For example, if lpBuffer points to the ASCII string 0x41, 0x0A, 0x0D, 0x1D (A\n\r^Z), the string passes the IS_TEXT_UNICODE_STATISTICS test, though failure would be preferable."
And the book "Programming application for microsoft windows by Jeffrey Ritcher" says that this function does not give accurate results if the text is too small to do the tests..
If u open the file explicitly in ASCII mode in notepad, you can see the text correctly..
There can be only 2 reasons why notepad shows the file correctly through wine.. One is there may be no unicode support in wine.. or wine has a much better statistical and deterministic methods than microsoft to determine the text is ASCII or Unicode..
But the possibility of second is very remote.
test with typing these strings for your self...
aaaa aaa aaa aaaaa
hows are you mammu
3. When you need to type some text into a Word document for test purposes, don't waste your time--let Word do the job for you. Let's say that you would like to type in a single four-sentence paragraph. Just click at a blank line in your document, type =rand(1,4) and press Enter. Word will automatically type: The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
The first number inside the parentheses is the number of paragraphs and the second number is the number of sentences in each paragraph. So, for 22 paragraphs of 22 sentences, you'd enter =rand(22,22).
#2 * *For those of you using Windows, do the following: *1.) Open an empty notepad file 2.) Type "Bush hid the facts" (without the quotes) *3 *.) Save it as whatever you want. 4.) Close it, and re-open it. *MAGIC
#3 *Open Microsoft Word and type =rand (200, 99) And then press ENTER Then see the magic...
This can help to understand why
1.Device names such as COM1, CON or LPT1 are reserved words, and they can't be used as folder or file names.
2. The reasons why notepad is not able to display any combination of string if the text contains the words with 4 3 3 5 number of letters..
Finally found out that its not a bug with notepad..
What happens is..
Whenever we open a text file in notepad, it determines whether the text is ASCII or Unicode.. But actually there is no way in the world to exactly determine whether the text is ASCII or Unicode.. There is a function called IsTextUnicode in windows API.. The function does some tests on the text based on statistical data.. This is what MSDN says about the function.."The function uses various statistical and deterministic methods to make its determination.. These tests are not foolproof. The statistical tests assume certain amounts of variation between low and high bytes in a string, and some ASCII strings can slip through. For example, if lpBuffer points to the ASCII string 0x41, 0x0A, 0x0D, 0x1D (A\n\r^Z), the string passes the IS_TEXT_UNICODE_STATISTICS test, though failure would be preferable."
And the book "Programming application for microsoft windows by Jeffrey Ritcher" says that this function does not give accurate results if the text is too small to do the tests..
If u open the file explicitly in ASCII mode in notepad, you can see the text correctly..
There can be only 2 reasons why notepad shows the file correctly through wine.. One is there may be no unicode support in wine.. or wine has a much better statistical and deterministic methods than microsoft to determine the text is ASCII or Unicode..
But the possibility of second is very remote.
test with typing these strings for your self...
aaaa aaa aaa aaaaa
hows are you mammu
3. When you need to type some text into a Word document for test purposes, don't waste your time--let Word do the job for you. Let's say that you would like to type in a single four-sentence paragraph. Just click at a blank line in your document, type =rand(1,4) and press Enter. Word will automatically type: The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
The first number inside the parentheses is the number of paragraphs and the second number is the number of sentences in each paragraph. So, for 22 paragraphs of 22 sentences, you'd enter =rand(22,22).
Sep 26, 2007
Make your Life easy for Debugging KSH Shell Script
One of the problem that’s comes while debugging the KSH script is to use echo command to check the script health.
Well KSH Script debugging in not very easy, one may want to test the script in a test environment and before publishing the script need to remove or comment debugging lines from source code.
Following mechanism could make you life easy.
Use following lines at the beginning of the script:
if [[ -z $DEBUG ]];then
alias DEBUG='# '
else
alias DEBUG=''
fi
Where ever you put a debugging line that is only for testing, use it in the following way:
DEBUG set –x
Or echo a parameter
DEBUG echo $PATH
Or set a parameter that is valid only during the test
DEBUG export LOGFILE=/tmp
Now the trick is before executing the script, set the DEBUG variable in the KSH shell as
# export DEBUG=yes
While the execution of the script, the DEBUG lines will be executed. Now when the script is published if you happen to forget deletion of the debuging lines; they shall never disturb the script execution.
Example
#!/usr/bin/ksh
#export DEBUG=yes # if u want to include debuging line
#export DEBUG="" # if u want to remove debuging line
if [[ -z $DEBUG ]];then
alias DEBUG='# '
else
alias DEBUG=''
fi
LOG_FILE=./out/script.out
DEBUG LOG_FILE=./out/script.out
function add {
a=$1 b=$2
return $((a + b))
}
# MAIN
DEBUG echo "test execution"
DEBUG echo "$(date) script execution" >>$LOG_FILEDEBUG
echo "if you do not know it:"
add 2 2echo " 2 + 2 = $?"
Make your life easy……
Well KSH Script debugging in not very easy, one may want to test the script in a test environment and before publishing the script need to remove or comment debugging lines from source code.
Following mechanism could make you life easy.
Use following lines at the beginning of the script:
if [[ -z $DEBUG ]];then
alias DEBUG='# '
else
alias DEBUG=''
fi
Where ever you put a debugging line that is only for testing, use it in the following way:
DEBUG set –x
Or echo a parameter
DEBUG echo $PATH
Or set a parameter that is valid only during the test
DEBUG export LOGFILE=/tmp
Now the trick is before executing the script, set the DEBUG variable in the KSH shell as
# export DEBUG=yes
While the execution of the script, the DEBUG lines will be executed. Now when the script is published if you happen to forget deletion of the debuging lines; they shall never disturb the script execution.
Example
#!/usr/bin/ksh
#export DEBUG=yes # if u want to include debuging line
#export DEBUG="" # if u want to remove debuging line
if [[ -z $DEBUG ]];then
alias DEBUG='# '
else
alias DEBUG=''
fi
LOG_FILE=./out/script.out
DEBUG LOG_FILE=./out/script.out
function add {
a=$1 b=$2
return $((a + b))
}
# MAIN
DEBUG echo "test execution"
DEBUG echo "$(date) script execution" >>$LOG_FILEDEBUG
echo "if you do not know it:"
add 2 2echo " 2 + 2 = $?"
Make your life easy……
Sep 21, 2007
Input String Validation
What if your validation logic just requires allowing only alphanumeric string with some special characters
Lets say it must not allow any special characters except (dollar sign $, underscore _, hyphen - , asterisk* and question mark?)
There could be many ways to implement the logic, but I love to do it using regular expressions.
So just use RegEx ValidString = new RegEx("^[-_A-Za-z0-9\?\*\*]$"); to verify the input is a valid string.
Ok job done, but what if you needs to identify the invalid character in user input.
The trick could be too just use the negative of above Regex.
RegEx InValidSplCharacter = new RegEx("[^-_A-Za-z0-9\?\*\*]");
So small way to do big things, this is what I love about Regular expression.
Lets say it must not allow any special characters except (dollar sign $, underscore _, hyphen - , asterisk* and question mark?)
There could be many ways to implement the logic, but I love to do it using regular expressions.
So just use RegEx ValidString = new RegEx("^[-_A-Za-z0-9\?\*\*]$"); to verify the input is a valid string.
Ok job done, but what if you needs to identify the invalid character in user input.
The trick could be too just use the negative of above Regex.
RegEx InValidSplCharacter = new RegEx("[^-_A-Za-z0-9\?\*\*]");
So small way to do big things, this is what I love about Regular expression.
Sep 18, 2007
Process performance counter is disabled" exception on Process.GetProcessesByName ( )
TheLearnedOne:Here's another possibility:
http://forums.grouper.com/archive/index.php/t-134.html
Extract:
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q248993
Even if you use the below procedure you shall get the same error. try it for your own.
Reenabling an Extension by Using Regedit.exe
WARNING: If you use Registry Editor incorrectly, you may cause serious problems that may require you to reinstall your operating system. Microsoft cannot guarantee that you can solve problems that result from using Registry Editor incorrectly. Use Registry Editor at your own risk.
Start Regedit.exe. (You cannot use Regedt32.exe because it does not allow searching for registry values.)
Click to select the following key
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
Select Find from the Edit menu.
In the Find What field, type Disable Performance Counters.
Click Find Next. This will locate a Performance key that may have this Registry value set to 1.
If the Registry value is set to 1, set the value to 0 or delete the Registry value.
Press F3 to find the next occurrence of this Registry value.
Repeat the previous two steps until there are no Performance keys that have the Disable Performance Counters value set to 1.
NOTE: Often the "Disable Performance Counters" value does not appear in the registry. The value can be created and given a DWORD value of 1 to disable counters.
refer to this Microsoft article
http://support.microsoft.com/default.aspx?kbid=300956
Basically after Latest SP2 Service Pack Update - the files perfc009.dat and perfh009.dat become corrupted.
http://support.microsoft.com/default.aspx?scid=kb;EN-US;314958
make backups of the two files in \windows\system32 with a .bak extension just in case you need them later...
Here are the 2 files put into the \Windows\System32 folder and see your application running.
perfc009.dat (http://www.calforums.com/perfc009.dat)
perfh009.dat (http://www.calforums.com/perfh009.dat)
source: http://www.experts-exchange.com/Programming/Languages/.NET/Q_21285890.html
http://forums.grouper.com/archive/index.php/t-134.html
Extract:
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q248993
Even if you use the below procedure you shall get the same error. try it for your own.
Reenabling an Extension by Using Regedit.exe
WARNING: If you use Registry Editor incorrectly, you may cause serious problems that may require you to reinstall your operating system. Microsoft cannot guarantee that you can solve problems that result from using Registry Editor incorrectly. Use Registry Editor at your own risk.
Start Regedit.exe. (You cannot use Regedt32.exe because it does not allow searching for registry values.)
Click to select the following key
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
Select Find from the Edit menu.
In the Find What field, type Disable Performance Counters.
Click Find Next. This will locate a Performance key that may have this Registry value set to 1.
If the Registry value is set to 1, set the value to 0 or delete the Registry value.
Press F3 to find the next occurrence of this Registry value.
Repeat the previous two steps until there are no Performance keys that have the Disable Performance Counters value set to 1.
NOTE: Often the "Disable Performance Counters" value does not appear in the registry. The value can be created and given a DWORD value of 1 to disable counters.
refer to this Microsoft article
http://support.microsoft.com/default.aspx?kbid=300956
Basically after Latest SP2 Service Pack Update - the files perfc009.dat and perfh009.dat become corrupted.
http://support.microsoft.com/default.aspx?scid=kb;EN-US;314958
make backups of the two files in \windows\system32 with a .bak extension just in case you need them later...
Here are the 2 files put into the \Windows\System32 folder and see your application running.
perfc009.dat (http://www.calforums.com/perfc009.dat)
perfh009.dat (http://www.calforums.com/perfh009.dat)
source: http://www.experts-exchange.com/Programming/Languages/.NET/Q_21285890.html
Working with the System.Diagnostic.Process Class
| Working with the System.Diagnostic.Process Class Introduction The System.Diagnostic.Process class is used for the starting and stopping of processes; and controlling and monitoring application. With this powerful class you can gain access to information and use it to create an instance of an application or stop a running process. This FAQ will cover how to get a list of running process and how to start a new process by calling an executable or a register file extension (like .doc). Why would you want to use the Process class? This class is the "Successor" to the Shell command in VB6. If you need to start an application with parameters, or get notified when it exits, this class provides the power and information you need. Note: All code provide assumes that you have the Imported the System.Diagnostics namespace. The simplest way to do this is to add the following line of code at the top of your file. Also, for the code posted in this FAQ output is dumped to the Output window using the Debug.WriteLine method. Code: Imports System.Diagnostics Getting Information Getting information from the current process. It's important to find out what information we can obtain from a Process, so let's take a look at the information available. This example will be using the GetCurrentProcess to retrieve a reference to the applications process component. To do this we will declare a variable and use the shared GetCurrentProcess method to retrieve the object reference. All further code in the section will build on this declaration. Code: Dim proc As Process = Process.GetCurrentProcess Now that we have a reference to our Process, let's find out what information it can tell us. There is a lot of information you can retrieve from a Process Object. Here are just a few of them. Code: ' Unique identifier for this process. Debug.WriteLine(proc.Id.ToString) ' Name of the process. Debug.WriteLine(proc.ProcessName) ' This process's native handle. Debug.WriteLine(proc.Handle.ToString) ' Caption of the main window. Debug.WriteLine(proc.MainWindowTitle) ' Window handle of the main window Debug.WriteLine(proc.MainWindowHandle) ' Base Priority Information. Debug.WriteLine(proc.BasePriority.ToString) ' Overall priority category Debug.WriteLine(proc.PriorityClass.ToString) ' Number of handles this process has opened. Debug.WriteLine(proc.HandleCount.ToString) ' Indicates whether the user interface of this process is responding. Debug.WriteLine(proc.Responding.ToString) There are more properties available including information on Processor and Memory usage. Getting a list of the Current Processes Getting a list of the current processes running on your system is an easy task. We can use the shared method GetProcesses() to retrieve this information. The GetProcesses() method returns an Array of Process components that we can further query to learn more about any given process. Code: ' Declare a Process class. Dim proc As Process ' Loop through the Processes and write the name of the Process to the output window. For each proc In Process.GetProcesses Debug.Writeline(proc.ProcessName) Next Starting a Process Starting a Process with the Shared Start method. Starting a Process is a manner of knowing what the path to the executable (or other object that can be started through the run command). The simplest way to do this is to use the Shared Start method of the Process class. This example will be using notepad.exe and a text file named info.txt. Code: ' Start an instance of Notepad. Process.Start("notepad.exe") ' Start an instance of Notepad and open the info.txt file. Process.Start("notepad.exe", "c:\info.txt") ' Start an instance of the application that is registered to txt files. ' Just like you would double-click a file in Windows Explorer. Process.Start("c:\info.txt") On most systems, the "txt" extension is registered to the Notepad application. This will start a new instance of Notepad and open the info.txt file. These shared methods offer a way to create a process, but if we need more control over the process we need to create an instance of the Process class itself and use the StartInfo object. Also the shared method will throw an error if we pass a file that is not registered with the system. Starting a Process using the Process Class and the StartInfo object. Starting a process using the StartInfo object is relatively easy. The only required property is StartInfo.FileName which is a string specifying what to start. So why would you use it. Simple, you can provide error handling if a file is not registered and specify the WindowStyle. Also creating an instance of the Process Class allows for notification when the process has exited through events. Below we will start notepad again and pass it the argument of "C:\info.txt" Code: ' Create an Instance of the Process Class Dim proc As New Process ' Provide the name of the application or file. proc.StartInfo.FileName = "notepad.exe" ' Specify the arguments. proc.StartInfo.Arguments = "c:\info.txt" ' Start the process. proc.Start Simple, right? Good. Using Events to find out when a process has Exited. The process class exposes two events; Disposed and Exited. Disposed is inherited from Component, Exited occurs when the process exits. First we need to create an event handler that will execute when the process exits. In our event handler, we will write the ExitCode and ExitTime properties to the output window. Code: Private Sub OnProcessExit(ByVal sender As Object, ByVal e As EventArgs) ' Avoid late binding and Cast the Object to a Process. Dim proc As Process = CType(sender, Process) ' Write the ExitCode Debug.WriteLine(proc.ExitCode) ' Write the ExitTime Debug.WriteLine(proc.ExitTime.ToString) End Sub So now we have an event handler, but how do we get the event handler to fire? To do this we must add two lines of code before we start our process. We need to set EnableRaisingEvents to True in order for the events to fire. We must also add an event handler to trap the Exited event and run our OnProcessExit method. Code: Dim proc As New Process ' Provide the name of the application or file. proc.StartInfo.FileName = "notepad.exe" ' Specify the arguments. proc.StartInfo.Arguments = "c:\info.txt" ' This will allow the Exited event to fire. proc.EnableRaisingEvents = True ' Add an event handler for this process. ' Run the OnProcessExit sub when this process exits. AddHandler proc.Exited, AddressOf OnProcessExit ' Start the process. proc.Start() Now when the process exits, the Exited Event will be raised and our OnProcessExit method will be called. Providing Error Handling Providing error handling is a crucial part of any application. With the process method you will want to catch any error that is raised. The most common error is a file not found, the second most common error is dealing with files that are not registered to any particular application. You can proactively avoid "file not found" errors by using the Shared Exists method of the System.IO.File class. We will use this later when we put everything together to create our StartProcess Method. Code: If System.IO.File.Exists(path) = False Then Exit Sub End If Dealing with files that are not registered in the system is a little different. When you use Windows Explorer and try to open a file that is not registered, you are prompted with the "Open With" dialog and can then choose the application to open the file with. This functionality is provided by the Process class by setting the ErrorDialog Property in the StartInfo object to True. Code: proc.StartInfo.ErrorDialog = True Putting it all together Now that we have an understanding of the Process component and some of the things we can do, I am going to share two methods that I use for starting a Process. Code: ' Method to Start a Process with Error Handling. Private Sub StartProcess(ByVal Path As String) ' Declare the Process variable. Dim proc As Process ' Ensure that the file exists If System.IO.File.Exists(Path) = False Then Exit Sub End If ' Create the Process component. proc = New Process ' Set EnableRaisingEvents to True. proc.EnableRaisingEvents = True ' Add an event handler to trap the Exited event. AddHandler proc.Exited, AddressOf OnProcessExit ' Build the StartInfo object. ' Set the FileName property to the argument that was passed. proc.StartInfo.FileName = Path ' Enable the ErrorDialog. proc.StartInfo.ErrorDialog = True ' Start the Process proc.Start() End Sub ' Event Handler for Process.Exited Event Private Sub OnProcessExit(ByVal sender As Object, ByVal e As EventArgs) ' Avoid late binding and cast the Object to a specific Process component. Dim proc As Process = CType(sender, Process) ' Write out the Exit information. Debug.WriteLine(proc.ExitCode) Debug.WriteLine(proc.ExitTime) ' Dispose and Clear the object. proc.Dispose() proc = Nothing End Sub source: http://vbcity.com/forums/topic.asp?tid=29605 |
Jul 9, 2007
With VB.NET, there is no TextWidth method of Object like we have in VB.
TextWidth : Returns the width of a text string as it would be printed in the current font of a Form, PictureBox, or Printer.
Syntax in VB
object.TextWidth(string)
The TextWidth method syntax has these parts:
object Optional. An object expression that evaluates to an object in the Applies To list. If object is omitted, the Form with the focus is assumed to be object.
String Required. A string expression that evaluates to a string for which the text width is determined. Parentheses must surround the string expression.
Remarks
The width is expressed in terms of the ScaleMode property setting or Scale method coordinate system in effect for object. Use TextWidth to determine the amount of horizontal space required to display the text. If string contains embedded carriage returns, TextWidth returns the width of the longest line.
So What do in VB.NET ?
Well there is a way. Suppose we need to acquire the width of text in a TextBox as TextBox1
Dim myGraphics As System.Drawing.Graphics
myGraphics = Me.CreateGraphics
MsgBox(myGraphics.MeasureString(TextBox1.Text, Me.Font).Width)
This Could be very helpful in MSFlex Grid
You need to Resize Column Width of MSFlexGrid depending upon the Maximum Text width
Private Sub SizeColumns()
Dim g As Graphics = Me.CreateGraphics()
Dim myGraphics As System.Drawing.Graphics
myGraphics = Me.CreateGraphics
Dim FlexWidth2Trans As Integer
FlexWidth2Trans = (1440 / g.DpiX)
NOTE: MSFlexGrid uses twips, but .NET uses pixels. So by multiplying the inches by 1440, the twips to pixel conversion now gives the same result as in the original
Dim row_num As Integer
Dim col_num As Integer
Dim max_width As Single
For col_num = 0 To AxMSFlexGrid1.Cols - 1
max_width = 0
For row_num = 0 To AxMSFlexGrid1.Rows - 1
If max_width < myGraphics.MeasureString(AxMSFlexGrid1.get_TextMatrix(row_num, col_num), Me.Font).Width Then max_width = myGraphics.MeasureString(AxMSFlexGrid1.get_TextMatrix(row_num, col_num), Me.Font).Width * FlexWidth2Trans End If Next row_num AxMSFlexGrid1.set_ColWidth(col_num, max_width + 240) Next col_num End Sub
TextWidth : Returns the width of a text string as it would be printed in the current font of a Form, PictureBox, or Printer.
Syntax in VB
object.TextWidth(string)
The TextWidth method syntax has these parts:
object Optional. An object expression that evaluates to an object in the Applies To list. If object is omitted, the Form with the focus is assumed to be object.
String Required. A string expression that evaluates to a string for which the text width is determined. Parentheses must surround the string expression.
Remarks
The width is expressed in terms of the ScaleMode property setting or Scale method coordinate system in effect for object. Use TextWidth to determine the amount of horizontal space required to display the text. If string contains embedded carriage returns, TextWidth returns the width of the longest line.
So What do in VB.NET ?
Well there is a way. Suppose we need to acquire the width of text in a TextBox as TextBox1
Dim myGraphics As System.Drawing.Graphics
myGraphics = Me.CreateGraphics
MsgBox(myGraphics.MeasureString(TextBox1.Text, Me.Font).Width)
This Could be very helpful in MSFlex Grid
You need to Resize Column Width of MSFlexGrid depending upon the Maximum Text width
Private Sub SizeColumns()
Dim g As Graphics = Me.CreateGraphics()
Dim myGraphics As System.Drawing.Graphics
myGraphics = Me.CreateGraphics
Dim FlexWidth2Trans As Integer
FlexWidth2Trans = (1440 / g.DpiX)
NOTE: MSFlexGrid uses twips, but .NET uses pixels. So by multiplying the inches by 1440, the twips to pixel conversion now gives the same result as in the original
Dim row_num As Integer
Dim col_num As Integer
Dim max_width As Single
For col_num = 0 To AxMSFlexGrid1.Cols - 1
max_width = 0
For row_num = 0 To AxMSFlexGrid1.Rows - 1
If max_width < myGraphics.MeasureString(AxMSFlexGrid1.get_TextMatrix(row_num, col_num), Me.Font).Width Then max_width = myGraphics.MeasureString(AxMSFlexGrid1.get_TextMatrix(row_num, col_num), Me.Font).Width * FlexWidth2Trans End If Next row_num AxMSFlexGrid1.set_ColWidth(col_num, max_width + 240) Next col_num End Sub
Jul 4, 2007
How to spawn console processes with redirected standard handles
This article describes how to redirect the input and output of a child process that receives input from the standard input handle or sends output to the standard output handle. The Win32 API enables applications to spawn a child console process with redirected standard handles. This feature allows a parent process to send and receive the input and output of the child process.
Note Some console based applications do not use the standard handles for their input/output (IO) operations. The Win32 API does not support redirection of these processes.
The CreateProcess() API through the STARTUPINFO structure enables you to redirect the standard handles of a child console based process. If the dwFlags member is set to STARTF_USESTDHANDLES, then the following STARTUPINFO members specify the standard handles of the child console based process: HANDLE hStdInput - Standard input handle of the child process.
HANDLE hStdOutput - Standard output handle of the child process.
HANDLE hStdError - Standard error handle of the child process.
You can set these handles to either a pipe handle, file handle, or any handle that can do synchronous reads and writes through the ReadFile() and WriteFile() API. The handles must be inheritable and the CreateProcess() API must specify that inheritable handles are to be inherited by the child process by specifying TRUE in the bInheritHandles parameter. If the parent process only wishes to redirect one or two standard handles, specifying GetStdHandle() for the specific handles causes the child to create the standard handle as it normally would without redirection. For example, if the parent process only needs to redirect the standard output and error of the child process, then the hStdInput member of the STARTUPINFO structure is filled as follows: hStdInput = GetStdHandle(STD_INPUT_HANDLE);
Note Child processes that use such C run-time functions as printf() and fprintf() can behave poorly when redirected. The C run-time functions maintain separate IO buffers. When redirected, these buffers might not be flushed immediately after each IO call. As a result, the output to the redirection pipe of a printf() call or the input from a getch() call is not flushed immediately and delays, sometimes-infinite delays occur. This problem is avoided if the child process flushes the IO buffers after each call to a C run-time IO function. Only the child process can flush its C run-time IO buffers. A process can flush its C run-time IO buffers by calling the fflush() function.
Note Windows 95 and Windows 98 require an extra step when you redirect the standard handles of certain child processes.
The following sample redirects the standard input, output, and error of the child process specified in the CreateProcess call. This sample redirects the provided console process (Child.c).
Sample code
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
Redirect.c
Description:
This sample illustrates how to spawn a child console based
application with redirected standard handles.
The following import libraries are required:
user32.lib
Dave McPherson (davemm) 11-March-98
--*/
#include
#pragma comment(lib, "User32.lib")
void DisplayError(char *pszAPI);
void ReadAndHandleOutput(HANDLE hPipeRead);
void PrepAndLaunchRedirectedChild(HANDLE hChildStdOut,
HANDLE hChildStdIn,
HANDLE hChildStdErr);
DWORD WINAPI GetAndSendInputThread(LPVOID lpvThreadParam);
HANDLE hChildProcess = NULL;
HANDLE hStdIn = NULL; // Handle to parents std input.
BOOL bRunThread = TRUE;
void main ()
{
HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
HANDLE hInputWriteTmp,hInputRead,hInputWrite;
HANDLE hErrorWrite;
HANDLE hThread;
DWORD ThreadId;
SECURITY_ATTRIBUTES sa;
// Set up the security attributes struct.
sa.nLength= sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
// Create the child output pipe.
if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
DisplayError("CreatePipe");
// Create a duplicate of the output write handle for the std error
// write handle. This is necessary in case the child application
// closes one of its std output handles.
if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
GetCurrentProcess(),&hErrorWrite,0,
TRUE,DUPLICATE_SAME_ACCESS))
DisplayError("DuplicateHandle");
// Create the child input pipe.
if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
DisplayError("CreatePipe");
// Create new output read handle and the input write handles. Set
// the Properties to FALSE. Otherwise, the child inherits the
// properties and, as a result, non-closeable handles to the pipes
// are created.
if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
GetCurrentProcess(),
&hOutputRead, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
DisplayError("DupliateHandle");
if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
GetCurrentProcess(),
&hInputWrite, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
DisplayError("DupliateHandle");
// Close inheritable copies of the handles you do not want to be
// inherited.
if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle");
if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle");
// Get std input handle so you can close it and force the ReadFile to
// fail when you want the input thread to exit.
if ( (hStdIn = GetStdHandle(STD_INPUT_HANDLE)) ==
INVALID_HANDLE_VALUE )
DisplayError("GetStdHandle");
PrepAndLaunchRedirectedChild(hOutputWrite,hInputRead,hErrorWrite);
// Close pipe handles (do not continue to modify the parent).
// You need to make sure that no handles to the write end of the
// output pipe are maintained in this process or else the pipe will
// not close when the child process exits and the ReadFile will hang.
if (!CloseHandle(hOutputWrite)) DisplayError("CloseHandle");
if (!CloseHandle(hInputRead )) DisplayError("CloseHandle");
if (!CloseHandle(hErrorWrite)) DisplayError("CloseHandle");
// Launch the thread that gets the input and sends it to the child.
hThread = CreateThread(NULL,0,GetAndSendInputThread,
(LPVOID)hInputWrite,0,&ThreadId);
if (hThread == NULL) DisplayError("CreateThread");
// Read the child's output.
ReadAndHandleOutput(hOutputRead);
// Redirection is complete
// Force the read on the input to return by closing the stdin handle.
if (!CloseHandle(hStdIn)) DisplayError("CloseHandle");
// Tell the thread to exit and wait for thread to die.
bRunThread = FALSE;
if (WaitForSingleObject(hThread,INFINITE) == WAIT_FAILED)
DisplayError("WaitForSingleObject");
if (!CloseHandle(hOutputRead)) DisplayError("CloseHandle");
if (!CloseHandle(hInputWrite)) DisplayError("CloseHandle");
}
///////////////////////////////////////////////////////////////////////
// PrepAndLaunchRedirectedChild
// Sets up STARTUPINFO structure, and launches redirected child.
///////////////////////////////////////////////////////////////////////
void PrepAndLaunchRedirectedChild(HANDLE hChildStdOut,
HANDLE hChildStdIn,
HANDLE hChildStdErr)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
// Set up the start up info struct.
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hChildStdOut;
si.hStdInput = hChildStdIn;
si.hStdError = hChildStdErr;
// Use this if you want to hide the child:
// si.wShowWindow = SW_HIDE;
// Note that dwFlags must include STARTF_USESHOWWINDOW if you want to
// use the wShowWindow flags.
// Launch the process that you want to redirect (in this case,
// Child.exe). Make sure Child.exe is in the same directory as
// redirect.c launch redirect from a command line to prevent location
// confusion.
if (!CreateProcess(NULL,"Child.EXE",NULL,NULL,TRUE,
CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi))
DisplayError("CreateProcess");
// Set global child process handle to cause threads to exit.
hChildProcess = pi.hProcess;
// Close any unnecessary handles.
if (!CloseHandle(pi.hThread)) DisplayError("CloseHandle");
}
///////////////////////////////////////////////////////////////////////
// ReadAndHandleOutput
// Monitors handle for input. Exits when child exits or pipe breaks.
///////////////////////////////////////////////////////////////////////
void ReadAndHandleOutput(HANDLE hPipeRead)
{
CHAR lpBuffer[256];
DWORD nBytesRead;
DWORD nCharsWritten;
while(TRUE)
{
if (!ReadFile(hPipeRead,lpBuffer,sizeof(lpBuffer),
&nBytesRead,NULL) || !nBytesRead)
{
if (GetLastError() == ERROR_BROKEN_PIPE)
break; // pipe done - normal exit path.
else
DisplayError("ReadFile"); // Something bad happened.
}
// Display the character read on the screen.
if (!WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),lpBuffer,
nBytesRead,&nCharsWritten,NULL))
DisplayError("WriteConsole");
}
}
///////////////////////////////////////////////////////////////////////
// GetAndSendInputThread
// Thread procedure that monitors the console for input and sends input
// to the child process through the input pipe.
// This thread ends when the child application exits.
///////////////////////////////////////////////////////////////////////
DWORD WINAPI GetAndSendInputThread(LPVOID lpvThreadParam)
{
CHAR read_buff[256];
DWORD nBytesRead,nBytesWrote;
HANDLE hPipeWrite = (HANDLE)lpvThreadParam;
// Get input from our console and send it to child through the pipe.
while (bRunThread)
{
if(!ReadConsole(hStdIn,read_buff,1,&nBytesRead,NULL))
DisplayError("ReadConsole");
read_buff[nBytesRead] = '\0'; // Follow input with a NULL.
if (!WriteFile(hPipeWrite,read_buff,nBytesRead,&nBytesWrote,NULL))
{
if (GetLastError() == ERROR_NO_DATA)
break; // Pipe was closed (normal exit path).
else
DisplayError("WriteFile");
}
}
return 1;
}
///////////////////////////////////////////////////////////////////////
// DisplayError
// Displays the error number and corresponding message.
///////////////////////////////////////////////////////////////////////
void DisplayError(char *pszAPI)
{
LPVOID lpvMessageBuffer;
CHAR szPrintBuffer[512];
DWORD nCharsWritten;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpvMessageBuffer, 0, NULL);
wsprintf(szPrintBuffer,
"ERROR: API = %s.\n error code = %d.\n message = %s.\n",
pszAPI, GetLastError(), (char *)lpvMessageBuffer);
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),szPrintBuffer,
lstrlen(szPrintBuffer),&nCharsWritten,NULL);
LocalFree(lpvMessageBuffer);
ExitProcess(GetLastError());
}
//////////////////////////////////////////////////////////////////////
// child.c
// Echoes all input to stdout. This will be redirected by the redirect
// sample. Compile and build child.c as a Win32 Console application and
// put it in the same directory as the redirect sample.
//
#include
#include
#include
void main ()
{
FILE* fp;
CHAR szInput[1024];
// Open the console. By doing this, you can send output directly to
// the console that will not be redirected.
fp = fopen("CON", "w");
if (!fp) {
printf("Error opening child console - perhaps there is none.\n");
fflush(NULL);
}
else
{
// Write a message direct to the console (will not be redirected).
fprintf(fp,"This data is being printed directly to the\n");
fprintf(fp,"console and will not be redirected.\n\n");
fprintf(fp,"Since the standard input and output have been\n");
fprintf(fp,"redirected data sent to and from those handles\n");
fprintf(fp,"will be redirected.\n\n");
fprintf(fp,"To send data to the std input of this process.\n");
fprintf(fp,"Click on the console window of the parent process\n");
fprintf(fp,"(redirect), and enter data from it's console\n\n");
fprintf(fp,"To exit this process send the string 'exit' to\n");
fprintf(fp,"it's standard input\n");
fflush(fp);
}
ZeroMemory(szInput,1024);
while (TRUE)
{
gets(szInput);
printf("Child echoing [%s]\n",szInput);
fflush(NULL); // Must flush output buffers or else redirection
// will be problematic.
if (!_stricmp(szInput,"Exit") )
break;
ZeroMemory(szInput,strlen(szInput) );
}
}
Note Some console based applications do not use the standard handles for their input/output (IO) operations. The Win32 API does not support redirection of these processes.
The CreateProcess() API through the STARTUPINFO structure enables you to redirect the standard handles of a child console based process. If the dwFlags member is set to STARTF_USESTDHANDLES, then the following STARTUPINFO members specify the standard handles of the child console based process: HANDLE hStdInput - Standard input handle of the child process.
HANDLE hStdOutput - Standard output handle of the child process.
HANDLE hStdError - Standard error handle of the child process.
You can set these handles to either a pipe handle, file handle, or any handle that can do synchronous reads and writes through the ReadFile() and WriteFile() API. The handles must be inheritable and the CreateProcess() API must specify that inheritable handles are to be inherited by the child process by specifying TRUE in the bInheritHandles parameter. If the parent process only wishes to redirect one or two standard handles, specifying GetStdHandle() for the specific handles causes the child to create the standard handle as it normally would without redirection. For example, if the parent process only needs to redirect the standard output and error of the child process, then the hStdInput member of the STARTUPINFO structure is filled as follows: hStdInput = GetStdHandle(STD_INPUT_HANDLE);
Note Child processes that use such C run-time functions as printf() and fprintf() can behave poorly when redirected. The C run-time functions maintain separate IO buffers. When redirected, these buffers might not be flushed immediately after each IO call. As a result, the output to the redirection pipe of a printf() call or the input from a getch() call is not flushed immediately and delays, sometimes-infinite delays occur. This problem is avoided if the child process flushes the IO buffers after each call to a C run-time IO function. Only the child process can flush its C run-time IO buffers. A process can flush its C run-time IO buffers by calling the fflush() function.
Note Windows 95 and Windows 98 require an extra step when you redirect the standard handles of certain child processes.
The following sample redirects the standard input, output, and error of the child process specified in the CreateProcess call. This sample redirects the provided console process (Child.c).
Sample code
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
Redirect.c
Description:
This sample illustrates how to spawn a child console based
application with redirected standard handles.
The following import libraries are required:
user32.lib
Dave McPherson (davemm) 11-March-98
--*/
#include
#pragma comment(lib, "User32.lib")
void DisplayError(char *pszAPI);
void ReadAndHandleOutput(HANDLE hPipeRead);
void PrepAndLaunchRedirectedChild(HANDLE hChildStdOut,
HANDLE hChildStdIn,
HANDLE hChildStdErr);
DWORD WINAPI GetAndSendInputThread(LPVOID lpvThreadParam);
HANDLE hChildProcess = NULL;
HANDLE hStdIn = NULL; // Handle to parents std input.
BOOL bRunThread = TRUE;
void main ()
{
HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
HANDLE hInputWriteTmp,hInputRead,hInputWrite;
HANDLE hErrorWrite;
HANDLE hThread;
DWORD ThreadId;
SECURITY_ATTRIBUTES sa;
// Set up the security attributes struct.
sa.nLength= sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
// Create the child output pipe.
if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
DisplayError("CreatePipe");
// Create a duplicate of the output write handle for the std error
// write handle. This is necessary in case the child application
// closes one of its std output handles.
if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
GetCurrentProcess(),&hErrorWrite,0,
TRUE,DUPLICATE_SAME_ACCESS))
DisplayError("DuplicateHandle");
// Create the child input pipe.
if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
DisplayError("CreatePipe");
// Create new output read handle and the input write handles. Set
// the Properties to FALSE. Otherwise, the child inherits the
// properties and, as a result, non-closeable handles to the pipes
// are created.
if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
GetCurrentProcess(),
&hOutputRead, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
DisplayError("DupliateHandle");
if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
GetCurrentProcess(),
&hInputWrite, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
DisplayError("DupliateHandle");
// Close inheritable copies of the handles you do not want to be
// inherited.
if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle");
if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle");
// Get std input handle so you can close it and force the ReadFile to
// fail when you want the input thread to exit.
if ( (hStdIn = GetStdHandle(STD_INPUT_HANDLE)) ==
INVALID_HANDLE_VALUE )
DisplayError("GetStdHandle");
PrepAndLaunchRedirectedChild(hOutputWrite,hInputRead,hErrorWrite);
// Close pipe handles (do not continue to modify the parent).
// You need to make sure that no handles to the write end of the
// output pipe are maintained in this process or else the pipe will
// not close when the child process exits and the ReadFile will hang.
if (!CloseHandle(hOutputWrite)) DisplayError("CloseHandle");
if (!CloseHandle(hInputRead )) DisplayError("CloseHandle");
if (!CloseHandle(hErrorWrite)) DisplayError("CloseHandle");
// Launch the thread that gets the input and sends it to the child.
hThread = CreateThread(NULL,0,GetAndSendInputThread,
(LPVOID)hInputWrite,0,&ThreadId);
if (hThread == NULL) DisplayError("CreateThread");
// Read the child's output.
ReadAndHandleOutput(hOutputRead);
// Redirection is complete
// Force the read on the input to return by closing the stdin handle.
if (!CloseHandle(hStdIn)) DisplayError("CloseHandle");
// Tell the thread to exit and wait for thread to die.
bRunThread = FALSE;
if (WaitForSingleObject(hThread,INFINITE) == WAIT_FAILED)
DisplayError("WaitForSingleObject");
if (!CloseHandle(hOutputRead)) DisplayError("CloseHandle");
if (!CloseHandle(hInputWrite)) DisplayError("CloseHandle");
}
///////////////////////////////////////////////////////////////////////
// PrepAndLaunchRedirectedChild
// Sets up STARTUPINFO structure, and launches redirected child.
///////////////////////////////////////////////////////////////////////
void PrepAndLaunchRedirectedChild(HANDLE hChildStdOut,
HANDLE hChildStdIn,
HANDLE hChildStdErr)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
// Set up the start up info struct.
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hChildStdOut;
si.hStdInput = hChildStdIn;
si.hStdError = hChildStdErr;
// Use this if you want to hide the child:
// si.wShowWindow = SW_HIDE;
// Note that dwFlags must include STARTF_USESHOWWINDOW if you want to
// use the wShowWindow flags.
// Launch the process that you want to redirect (in this case,
// Child.exe). Make sure Child.exe is in the same directory as
// redirect.c launch redirect from a command line to prevent location
// confusion.
if (!CreateProcess(NULL,"Child.EXE",NULL,NULL,TRUE,
CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi))
DisplayError("CreateProcess");
// Set global child process handle to cause threads to exit.
hChildProcess = pi.hProcess;
// Close any unnecessary handles.
if (!CloseHandle(pi.hThread)) DisplayError("CloseHandle");
}
///////////////////////////////////////////////////////////////////////
// ReadAndHandleOutput
// Monitors handle for input. Exits when child exits or pipe breaks.
///////////////////////////////////////////////////////////////////////
void ReadAndHandleOutput(HANDLE hPipeRead)
{
CHAR lpBuffer[256];
DWORD nBytesRead;
DWORD nCharsWritten;
while(TRUE)
{
if (!ReadFile(hPipeRead,lpBuffer,sizeof(lpBuffer),
&nBytesRead,NULL) || !nBytesRead)
{
if (GetLastError() == ERROR_BROKEN_PIPE)
break; // pipe done - normal exit path.
else
DisplayError("ReadFile"); // Something bad happened.
}
// Display the character read on the screen.
if (!WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),lpBuffer,
nBytesRead,&nCharsWritten,NULL))
DisplayError("WriteConsole");
}
}
///////////////////////////////////////////////////////////////////////
// GetAndSendInputThread
// Thread procedure that monitors the console for input and sends input
// to the child process through the input pipe.
// This thread ends when the child application exits.
///////////////////////////////////////////////////////////////////////
DWORD WINAPI GetAndSendInputThread(LPVOID lpvThreadParam)
{
CHAR read_buff[256];
DWORD nBytesRead,nBytesWrote;
HANDLE hPipeWrite = (HANDLE)lpvThreadParam;
// Get input from our console and send it to child through the pipe.
while (bRunThread)
{
if(!ReadConsole(hStdIn,read_buff,1,&nBytesRead,NULL))
DisplayError("ReadConsole");
read_buff[nBytesRead] = '\0'; // Follow input with a NULL.
if (!WriteFile(hPipeWrite,read_buff,nBytesRead,&nBytesWrote,NULL))
{
if (GetLastError() == ERROR_NO_DATA)
break; // Pipe was closed (normal exit path).
else
DisplayError("WriteFile");
}
}
return 1;
}
///////////////////////////////////////////////////////////////////////
// DisplayError
// Displays the error number and corresponding message.
///////////////////////////////////////////////////////////////////////
void DisplayError(char *pszAPI)
{
LPVOID lpvMessageBuffer;
CHAR szPrintBuffer[512];
DWORD nCharsWritten;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpvMessageBuffer, 0, NULL);
wsprintf(szPrintBuffer,
"ERROR: API = %s.\n error code = %d.\n message = %s.\n",
pszAPI, GetLastError(), (char *)lpvMessageBuffer);
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),szPrintBuffer,
lstrlen(szPrintBuffer),&nCharsWritten,NULL);
LocalFree(lpvMessageBuffer);
ExitProcess(GetLastError());
}
//////////////////////////////////////////////////////////////////////
// child.c
// Echoes all input to stdout. This will be redirected by the redirect
// sample. Compile and build child.c as a Win32 Console application and
// put it in the same directory as the redirect sample.
//
#include
#include
#include
void main ()
{
FILE* fp;
CHAR szInput[1024];
// Open the console. By doing this, you can send output directly to
// the console that will not be redirected.
fp = fopen("CON", "w");
if (!fp) {
printf("Error opening child console - perhaps there is none.\n");
fflush(NULL);
}
else
{
// Write a message direct to the console (will not be redirected).
fprintf(fp,"This data is being printed directly to the\n");
fprintf(fp,"console and will not be redirected.\n\n");
fprintf(fp,"Since the standard input and output have been\n");
fprintf(fp,"redirected data sent to and from those handles\n");
fprintf(fp,"will be redirected.\n\n");
fprintf(fp,"To send data to the std input of this process.\n");
fprintf(fp,"Click on the console window of the parent process\n");
fprintf(fp,"(redirect), and enter data from it's console\n\n");
fprintf(fp,"To exit this process send the string 'exit' to\n");
fprintf(fp,"it's standard input\n");
fflush(fp);
}
ZeroMemory(szInput,1024);
while (TRUE)
{
gets(szInput);
printf("Child echoing [%s]\n",szInput);
fflush(NULL); // Must flush output buffers or else redirection
// will be problematic.
if (!_stricmp(szInput,"Exit") )
break;
ZeroMemory(szInput,strlen(szInput) );
}
}
Jul 3, 2007
Various methods for launching another program from one program VC++
There are several methods for launching another program from one program.
You can use _spawn(), _exec(), system(), WinExec(), ShellExecute(), ShellExecuteEx(), and CreateProcess().
The system() function is a more portable function.
WinExec(), ShellExecute(), ShellExecuteEx(), and CreateProcess() are unique to Windows programming. All four windows functions allow for launching an application in the background (window-hidden).
The WinExec() is the easiest of the four to use. It only takes two arguments, however MS recommends using the CreateProcess() instead of WinExec on all 32-bit programs.
The ShellExecute() is easier to setup then CreateProcess, and it has more options then WinExec. However, it's also a legacy function. MS recommends using ShellExecuteEx() for Win32 applications.
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpVerb,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
The ShellExecuteEx() only takes one parameter, but the parameter is a structure with many members, and it's almost as compicate as the CreateProcess() function.
BOOL ShellExecuteEx(
LPSHELLEXECUTEINFO lpExecInfo
);
The CreateProcess() function takes 10 parameters, and can be tricky to use.
int system( const char *command );
UINT WinExec(
LPCSTR lpCmdLine, // address of command line
UINT uCmdShow // window style for new application
);
BOOL CreateProcess(
LPCTSTR lpApplicationName,
// pointer to name of executable module
LPTSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // thread security attributes
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCTSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION
);
You can use _spawn(), _exec(), system(), WinExec(), ShellExecute(), ShellExecuteEx(), and CreateProcess().
The system() function is a more portable function.
WinExec(), ShellExecute(), ShellExecuteEx(), and CreateProcess() are unique to Windows programming. All four windows functions allow for launching an application in the background (window-hidden).
The WinExec() is the easiest of the four to use. It only takes two arguments, however MS recommends using the CreateProcess() instead of WinExec on all 32-bit programs.
The ShellExecute() is easier to setup then CreateProcess, and it has more options then WinExec. However, it's also a legacy function. MS recommends using ShellExecuteEx() for Win32 applications.
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpVerb,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
The ShellExecuteEx() only takes one parameter, but the parameter is a structure with many members, and it's almost as compicate as the CreateProcess() function.
BOOL ShellExecuteEx(
LPSHELLEXECUTEINFO lpExecInfo
);
The CreateProcess() function takes 10 parameters, and can be tricky to use.
int system( const char *command );
UINT WinExec(
LPCSTR lpCmdLine, // address of command line
UINT uCmdShow // window style for new application
);
BOOL CreateProcess(
LPCTSTR lpApplicationName,
// pointer to name of executable module
LPTSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // thread security attributes
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCTSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION
);
How to convert Twips to Pixels and back again
Description: Visual Basic uses Twips by default instead of pixels, this shows how to convert between them
Its very easy to convert between Twips and Pixels, using the Screen object.
Heres how to convert from Twips to Pixels for Horizontal (X axis) positions:
CODE: Pixels = Twips / Screen.TwipsPerPixelX
And for Vertical (Y axis) positions:
CODE: Pixels = Twips / Screen.TwipsPerPixelY
To convert back again, just use (for horizontal):
CODE: Twips = Pixels * Screen.TwipsPerPixelX
And for vertical:
CODE: Twips = Pixels * Screen.TwipsPerPixelY
On most systems you can use either horizontal or vertical but I presume in some cases you can't, so its best to use the correct ones.
MSFlexGrid uses twips, but .NET uses pixels. You can use the code below to
convert pixels to twips:
Private m_TwipsPerPixelX As Integer
Private m_TwipsPerPixelY As Integer
....
Using g As Graphics = Me.CreateGraphics()
m_TwipsPerPixelX = 1440 / g.DpiX
m_TwipsPerPixelY = 1440 / g.DpiY
End Using
....
Me.MSFlexGrid1.ColWidth = 100 * m_TwipsPerPixelX
Its very easy to convert between Twips and Pixels, using the Screen object.
Heres how to convert from Twips to Pixels for Horizontal (X axis) positions:
CODE: Pixels = Twips / Screen.TwipsPerPixelX
And for Vertical (Y axis) positions:
CODE: Pixels = Twips / Screen.TwipsPerPixelY
To convert back again, just use (for horizontal):
CODE: Twips = Pixels * Screen.TwipsPerPixelX
And for vertical:
CODE: Twips = Pixels * Screen.TwipsPerPixelY
On most systems you can use either horizontal or vertical but I presume in some cases you can't, so its best to use the correct ones.
MSFlexGrid uses twips, but .NET uses pixels. You can use the code below to
convert pixels to twips:
Private m_TwipsPerPixelX As Integer
Private m_TwipsPerPixelY As Integer
....
Using g As Graphics = Me.CreateGraphics()
m_TwipsPerPixelX = 1440 / g.DpiX
m_TwipsPerPixelY = 1440 / g.DpiY
End Using
....
Me.MSFlexGrid1.ColWidth = 100 * m_TwipsPerPixelX
Subscribe to:
Posts (Atom)