Possibility

Hi Dr. XXXX,

    It is a naive thought and I hope you have time to give me some hints as to this lenghy, trivial puzzle to me.

   It always bothers me a lot when I planned in c++ to design a class of logic object which describes any proposition as an object of this class. In my intuition, this class is to store all characteristics of a proposition such as the language expression of the proposition, the truth value, the possible logic operations rule like "and", "or" etc. It seems quite simple for me at beginning to overload the operator to implement logic operations. 

    But then I run into a puzzle, it seems that I can never assign truth value to a certain proposition as almost all proposition's truth value is uncertain. For example, "Today is colder than yesterday". I never know if this proposition is true or false as "today" and "yesterday" is undefined and the truth value varies when "today" is changing. What's worse, if I don't check the weather data from certain source like weather forecast, message from others, or try it by myself etc., I will have no way to settle the truth value of this proposition. And even I do all checking, still there will be some reason, I might give the wrong value, such as I checked wrong data, people lied to me, I have a fever....  So, I began to think all proposition is undefined with their truth value unless I explicitly assign one for it.

    Yet it changed my view when we look at the proposition like "2 is bigger than 1" which is always true with no need to justify. I try to figour out that some propositions are describing "facts", some are describing "rules",and some are dealing with "hyperthesis" etc. However, it is still not a convincing explanation to me though I cannot tell why. 

    I am taking a statistic course "STAT 249" which greatly surprises me by applying many similar methods of logical operations. It hints me that maybe every proposition is indeed having a certain possibility to be true or false. Say "today is colder than yesterday" is only having roughly 50% of chance to be correct. Yet "2 is bigger than 1" is 100% of chance to be correct. Then we might define all proposition to be a kind of function of time t:  proposition p--->f(t)   where the range of function f(t) is either 1 or 0, or in other word true or false. For some proposition like "2 is bigger than 1"  always has value of 1 for any value of t, that is always true for all time. And for other propositions, the value of function is varying between 1 and 0, that is sometimes true and sometimes false depending the domain of time t. This seems to explain well for my puzzle. Even for the most trouble one---truth simbol like "true" and "false", it gives a perfect solution: they are simply const function with value of 1 and 0 respectively for all possible time t.

    Anyway there seems to be another approach to solve the problem with "2 is bigger than 1" by dissecting the proposition into several more propositions like: p= {"it is 2"}, q = {"it is 1"} , r ={"first is bigger than second"}; 

    Then we can define: (p^q)-->r

For proposition like "today is colder than yesterday", it will be very complicated to change it into more propositions:

    p = {temperature of today};  q= {temperature of yesterday}; 

    r = {the first is bigger than second}  ; s = {the first is colder than second}

    Then we can define: r(p, q) --->s(p,q)

    And this solution is not uniformal but maybe practical. It requires too much analysis for language itself. So it may not be practical for computer compared with the "statistic view" of truth value. 

    In my view, it is always a similar for human to recognize if a proposition is true or not by collecting some sample with experiments or observations at very early stage. As the accumulation of result of this proposition or hyperthesis goes up, the man counts the possibility or the number of truth value of that proposition. Then the truth value of a certain proposition is established on basis of "possibilities". So, it is also a good way to describe all propositions in this way to imitate the process of human being.   

    Thank you for your time and I am waiting for your advice.

                关于数字显示的方法及其除法

Hi,

我的问题是怎样显示一个数字呢?我能想到的办法就是用连续除以10,将余数存入stack,直到商为0。再从stack中将余数一一取出,加30h显示。可是,我碰到一些问题:

1。8位和16位除法不同,我必须根据被除数大小采用两种不同的除法。所以,在作16位除法时我每次都要去判断结果是8位还是16位,以便采用不同的除法。这样会有问题吗?

2。我在codeview里无法trace,因为我运行时候总是报divide overflow的错误,后来我在dos环境里,直接运行cv去debug,一步步都ok,甚至结果都看到了,是正确的。可是,codeview里还是不能运行,直接运行exe文件还是报divide overflow的错误。我想知道,作除法时,怎样判断divide overflow的?是看flag 寄存器的某一个标志位吗?

谢谢。

黄清浙

.DOSSEG

.MODEL SMALL

.STACK 100H

.DATA
ARRAY DB 115,125,125,140,110
MSG DB "IT IS 3!", "$"

BUFFER DB 10 DUP(?)

.CODE

START:

            MOV AX, @DATA
            MOV DS, AX

            MOV AX, OFFSET ARRAY
            PUSH AX
            MOV AX, 5
            PUSH AX

            CALL SUMARRAY
            XOR AX, AX
            POP AX


            MOV BL, 10
            XOR CX, CX
    ;MOV AH, 0
    CMP AH, 0
    JNE DOUBLEDIVIDE

DIVIDE:
    DIV  BL
            XOR DX, DX
    MOV DL, AH
    MOV AH, 0
            ADD DL, 30H
            PUSH DX  ; STORE RESULT IN STACK
            INC CX  ; COUNTER +1
            CMP AL, 0
            JE  ENDDIVIDE
    JMP DIVIDE
DOUBLEDIVIDE:
    DIV BX
    ADD DL, 30H
    PUSH DX
    INC CX
    CMP AX, 0
    JE ENDDIVIDE
    JMP DOUBLEDIVIDE



ENDDIVIDE:
    POP DX;
            MOV AH, 02H
            INT 21H
            LOOP ENDDIVIDE

ENDQUICK:

            MOV AX, 4C00H
            INT 21H



SUMARRAY  PROC NEAR

GETPARAM:
        PUSH BP;
        MOV BP, SP

        PUSH BX;
        PUSH CX
PUSH DX
PUSH AX

        MOV CX, [BP+4]   ;ARRAY SIZE
        MOV BX, [BP+6]   ; ARRAY ADD
        MOV DX, 0;   SUM
SUMLOOP:
MOV AX, [BX]
MOV AH, 0
ADD DX, AX
        ADD BX, 1;
        LOOP SUMLOOP;
        MOV [BP+6], DX;  PUSH RESULT IN STACK
POP AX
POP DX
        POP CX
        POP BX
        POP BP
        RET 2;
SUMARRAY ENDP


END START


Nick Huang

Qustion:
黄兄你好, 小弟有如下数题百思不得其解,恳请指点。 还有几个关于SET的概念:A∪B = { Q(x)→P(Q)} =  ?? *∪B = { P(Q)→Q(x)} =  ??   

Answer:

1. Assignment3 No.3: 这个题目的意思是确定f是否为onto.在确定是否为onto时候其实我们更关心的是co-domain里是否每一个元素都有包括在function f里面。显然,这道题里面的自变量有两个,m,n。我们要确定的是这两个子变量所组成的函数的值是否覆盖了整个自然数。例如,iii)f(m,n) = |m|+|n| 很明显的,他的值是非负的,所以,一定没有覆盖所有的自然数。经验就是,讨论是否onto时候,主要关心的是co-domain的值,至于domain不要被他的复杂所迷惑。

2。Assignment3 no.6:   这个题目的意思是求组合函数。在学了关系(relation)以后,可以更好的理解,如f@g,假如我们把f,g看作关系(函数本身就是一种关系)那么就表示为从关系g的起始集合里的某个元素a对应g的终止集合里的某个元素b,同时这个元素b恰好是关系f的起始集合里的元素,那么关系f里b所对应的终止集合的元素c就和a组成了一种新的关系,这个新的关系就是组合关系f@g。

请注意,这里是g的起始元素到f的终止元素,和记号f@g的顺序正好相反。 

 回到函数,f@g就是表示函数g是函数f的自变量,也就是复合函数,所以,你只需要把函数f的自变量用函数g来替换就可以了。

3。A3 no. 12ii) a congruent b(mod m) ==> gcd(a,m)==gcd(b,m)

这个题目有几种思路。 最简单的是应用欧几里德算法的一个推论(p178) a = bq+r ==>gcd(a,b)==gcd(b,r)

从题目知:m|a - b(congruent定义)==> exist q(a- b = qm) (整除的定义)==〉exist q(a= b + qm)(移项)

==〉gcd(a,b) = gcd(b,m) (运用上述的推论)

solution中实际上给出了一个对推论的简单证明:

a - qm 和 a - m有同样的divisor(可以找一找书上的定理或者简单证明如下:

exist x(x|a and x|m)(假设a和m有同样的divisor的话) ==>exist x exist q(x|a-qm and x|m)

(这个是定理,p154 corollary,就是m=1,n=-q的情况.)

==> gcd(a,m) == gcd(a-qm,m)(因为gcd是公约数中最大的一个而已。)

在运用题目的部分:

m|a - b(congruent定义)==> exist q(a- b = qm) (整除的定义)==〉exist q(b= a- qm)(移项)

所以, gcd(a,m) = gcd(a-qm, m) = gcd(b, m)(把b=a-qm代入)

4。 A3 no. 14.:这个题目的证明很繁杂,solution的思路也比较难想到,我的证明想法就是tutor的提示,先考虑n是否能被5整除,就是n=5k如果能被5整除可以很容易去证明底数是80的那个(当然你还是要用到题目要求的n市奇数的条件,所以你要进一步假设k是奇数k=2h+1,所以n=5(2h+1) = 10h+5)

当n不能被5整除时候,分4种情况:余数分别是1,2,3,4,同时类似地让n还是奇数,比如余数为2时候,n=5k+2,这时候k只能是奇数n才能是奇数,所以,n=5(2h+1)+2 = 10h+7。这样你再参考以下solution的方法判断奇偶数,就可以了。

5。 A3 no. 15:这些题目你要参考tutorial的笔记,要点就是比如第二题:x~2 congruent 3(mod 4)这一步有一个隐含的结论就是{x~2 mod 4|x is integer} =={x~2 mod 4| x =0, 1,2,3}, 就是说x平方除以4的余数等于x取0,1,2,3所得的余数一样,这个证明,你可以看一下tutorial的笔记,或者你记住这个结论也应该可以吧。

6。A3 no. 16:这个题目前面1,2的证明应该很简单,全部是根据floor, ceil的定义。第3,4的证明我觉得solution的反证法不好,因为,考虑的情况应该有4种,很麻烦,不如我的证明法简单易懂。

7。A3 no. 17:这个题目证明有很多小题,你对那一题不清楚呢?或者,星期一早上到H-513碰头再说吧。

8。 AB = { Q(x)→P(Q)} = (这里有一点错误,第一个B应该为B的补集--complement,你是从哪里拷贝的?我还真没有办法找到这样的图片来改正。哈哈。)

    * B = { P(Q)→Q(x)} =

简单的证明可以帮助你理解:

假定 P(x) <==>(def) x in A;  Q(x) <==> (def) x in B

x in A U not B <==> all x( x in A  or not x in B) <==> all x[not Q(x) or P(x)]  

<==> all x[Q(x) --> P(x)] (注意这里都是逻辑关系,我只是说了如果有一个元素x属于这个集合的话就相当于逻辑上的相应关系。)

而集合是可以有逻辑关系来定义的。比如:{x| (x in A) or (not x in B)}就定义了上述集合。

而从集合的运算我们又可以得到:(我贴不出了,相信你明白的。)

所以,我的经验就是,集合是集合,逻辑是逻辑,符号和关系只是类似,并不能混用,但是两者又有联系,集合可以用逻辑来定义,逻辑可以用集合来表现,更好理解。

最后一个就是exclusive or,你可以在图上的红点和灰点看出来。

                         关于不定指令集的问题

    这是我的备忘录,将来学comp229再来解决:在固定指令集中,fetch总是可以取到完整的一条指令。可是,在不定指令集中

怎么才能取到下一条完整指令?该取多少bytes?

    这个问题解决了:问朱春明同学,他说的很好,我们就取最长的指令好了,有什么关系?反正纪录的是下一条指令的首地

址。好!

                关于RSA加密系统的猜想

问题:

您好!有个加密问题想请教您,比如rijindael 是256bit 加密的,如果我的password是8位或100位,是否破解时间一样(用穷举法)。这里所指的258bit是怎样一种概念,是否最长password为256位。

我的解答:

老实说, 我并不是很确定256bit加密究竟是怎样的,但是,以我现在学到的离散数学的知识,我猜想他应该是应用RSA公共密匙系统,因为这是互联网上最普遍应用的一种加密系统。所谓公共密匙实际上是建立在余数定理上的一种算法。他的基本算法不复杂,任何一本 离散数学的书里应该都有,我也写过这样的加密解密程序:
http://www3.sympatico.ca/qingzhehuang/RSA2.htm
首先,我解释一下公共密匙的概念,以往的私有密匙的问题在于,你知道加密的密匙,一般你就自然知道怎样解密了。所以,当你把密匙一起随信息传送的时候,如果,密匙被截获,加密就毫无秘密可言了。公共密匙是即使你知道了加密的密匙,你要破解解密的密匙,所要耗费的时间是比天文数字还要大,所以,几乎不可能。
具体算法解释起来需要不少数学基础知识和定理,原理简单说来就是,寻找两个非常大的质数p,q,把他们的乘积作为公共密匙分发给用户来加密解密,这样,而加密的钥匙exp是每一个用户自定义的加密的钥匙,当然有一定的规则。加密时候,把每一个字母或数字的exp的幂除以p*q的余数就是加密的结果。而解密的时候,必须利用(p-1)*(q-1)的乘积结合exp来计算出一个解密的钥匙dexp,每一个加密的数字的dexp次幂除以p*q的余数就还原成原来的结果,这里面有一系列的证明。
最本质的问题在于要破解密码必须要知道dexp,而要知道dexp必须要知道(p-1)*(q-1),而要知道(p-1)*(q-1)单单靠知道p*q的乘积对你并没有多少帮助,你可以想象你要计算
(p-1)*(q-1)唯一的办法就是知道p和q。从公共密匙p*q推算出p和q,除了一个个的尝试,没有更好的办法,因为p,q是质数,单单知道他们的乘积没有给你任何捷径来计算p和q。
当我们选择两个非常大的p,q,比如各自有200位数字,或者要256bit才能表示的质数时候(这是一个非常大的数字了换成10进制有将近100位数字。),理论上从p*q来计算出p和q用最强的计算机也要几十亿年。(关于时间我们的教科书上没有说是十进制的200位还是2进制,我想差不多都是太长太长了。)
所以,如果我猜想的不错,256bit加密法用穷举的办法来破解几乎是不可能的。你的自定义的密匙exp的长度在这里与破解p和q并无直接的关系,因为你最终无论如何都要知道p和q才能计算出解密的dexp。
当然,这一切都是建立在加密系统为RSA的基础上的,我曾经观察过这里银行,学校等等的密码验证加密系统都是RSA。你可以双击浏览器的底边上的那把小黄色的锁,看加密的证书系统,看看是不是有一个public key RSA 1024bits 或者256bits就知道了。
你如果对RSA系统还有什么问题,我们尽可以一起讨论。

    逻辑仅仅是征途上的航标灯???

    假如给我们一棵搜索树,每个节点代表一个逻辑判断,从一个已知真伪的节点出发根据一系列的所谓“逻辑”关系去试图到达某一个目的节点,这个过程我们通常称作“逻辑推理”。从广义的搜索来看,逻辑的与或仅仅是节点之间相对关系。

    例如,所谓“或”说的是当你到达某一个节点继续前进有一系列子节点供选择时候,从“或”中任意选一个都可以继续。

    所谓“与”说的是当你达到某一个节点继续前进有一系列子节点供选择时候,必须要同时选择这些子节点才可以继续前进,可是,我们真的有“分身术”同时走多个路径吗?

    这其中似乎蕴含着某种深奥的东西,绝非“串联,并联”这么肤浅。

    我在想也许几百年后的考古学家都是计算机,他们所感兴趣的课题就是人类的思想发展,那么我的这些日记加垃圾就是一份极好的素材。

这个问题很严重

问题:

我最近有个作业是叫用Matlab做的我知道是比较简单的但我的确不会做啊
试求一个3行3列矩阵A:
          1.各行各列元素和为7,各元素>=0.
          2.
                        ┌─┐          ┌─┐
                          1              3.5
                A   *    0.5      =      3.5
                          0              3.5 
                        └─┘          └─┘
          3.用MATLAB 软件实现.  

回答:

hi,
1. 我没有用过matlab不懂,很抱歉,不过,我想他的原理和maple应该差不多,是工程计算的,对吧?(实际上我也没有用过maple,这里纯粹有些无端了。)
2。 不过问题应该不会太难,我向所有的软件都可以解决一个基本的问题:多元一次方程组的解是可以用软件计算的。这个只要学过线性代数的就知道,用矩阵来表示系数,用消元法,我自己就写过,很早以前了,(大约是在冬季。 哈哈。。。)
http://www.staroceans.com/Matrix3.htm
所以,我敢肯定你所说的matlab一定有这个基本的功能,问题是怎样表达:
你的矩阵式3x3就是说有9个未知数,所以需要9各独立方程,你的各行各列的和给了你6各方程,你还需要3格,这三个就是最后那个矩阵乘法,我想你一定知道,这个乘法会再给你3各方程吧?这样你就已经获得了求解所必要的9x9的矩阵系数了,明白我的意思吗?你所要求解的9个变量应该组成的方程式:
a1A+b1B+c1C+d1D+e1E+f1F+g1G+h1H+i1I = const1
a2A+b2B+c2C+d2D+e2E+f2F+g2G+h2H+i2I = const2
...
a9A+b9B+...                                        
其中的a1,b1...这些就是你的系数,他们可以为零,你有这样9个独立的方程式,就可以解9个变量了。
假如matlab不提供这个基本功能,或者你找他们索赔,或者我写给你,(就在我的链接里,应该有,我忘了。)哈哈,开玩笑了。
以上都是开玩笑,但是你的问题给我了当头一棒,因为,他非常的重要:就是我所写的所有的搜索的问题都是有一个起始点,或者说搜索树有一个root,可是你提出的问题,却是目前我无法解决的:无限的搜索,无根的搜索树!这个问题很严重!首先,对自然数我可以用归纳法的模式扩展,因为,自然数是一个well-ordered的集合,它有一个最小值0,可是队有理数就没有办法了。其次,搜索的初始条件是不确定的,下次搜索需要增加的差值,也是不确定的,这个问题似乎是自动机模型所不能解决的,我一点主意也没有。谢谢你的问题,请允许我把这个问题记录在我的网页上。
希望对你有帮助,你是学工程的吧?
Nick Huang/Qingzhe Huang

真正的问题:

在我心目中基本上任何问题都可以用一个搜索来解决,只是搜索的级别不同,或者说层面,这个意思不好表达,比如我们有一个函数,我们让他去解决一个问题,可是当我们有很多的函数解决具体的问题,我们需要一个更高级的函数来调用这一系列函数来解决一个更高级的问题,这就是high-order-function的意思。而所有的搜索都是基于一个有根的树,这一点不妨用自动机的角度来看,我们可以有很多的或者根本没有final state,可是不能没有起始点,而且只能有一个。这一点从数据结构的角度来看,我们不允许重复,因为,有环的搜索只会陷入死循环。树的定义就是没有环的图。

问题是我们找不到起始点,或者说有无限或者说有很多的可能的起始点的话,我们的搜索会变得不可行,这才是问题!   

这个证明是否合理?

hi,
我很想听听各位对comp335里关于“计算机程序不能证明某些问题的证明”。
原来的证明简要如下:
http://www.staroceans.com/helloworld.htm#problem
假设有一个程序turing可以把另一个程序的输出作为他的输入,然后检测这个输入是否为"hello,world"在输出一个检测结果。
比如,如果输入为"hello,world",则程序输出"yes",反之则输出"hello, world"。(这里,我们可以认为输入程序没有任何输出也形同一种输出,即没有输出"hello,world"。)
现在,假设以turing程序自身作为自己的输入程序来检验自己,书上的证明是这样的,假如,程序最终的输出为"yes",则意味着输入程序的地输出为"hello,world",可是,根据假设我们的turing程序输出的是"yes",这是矛盾的。所以,这样的turing程序是不可能存在的。所以证明了有些问题是计算机程序所不可能解决的。
http://www.staroceans.com/helloworld.htm#explain
问题在于,我对这个证明有些怀疑:我们都知道program这个概念一般是指source code。而程序在运行的时候我们称之为process。一个program可以由多个process。而且这些process可以有不同的行为,取决于具体的运行环境。
因此,问题中的两个turing程序应该理解为两个turing program的两个process。自然两个process是可以有独立的输入输出,也自然有着互不相干的运行结果,所以,以上的证明中的矛盾并不存在,因为压根就使两个不同的输入输出,何来矛盾之有?
各位对此有什么看法?
Nick Huang/Qingzhe Huang

         与jeppeter君商榷

>I am interesting with you site ,and i think that the CFGReader 
> can be rewrite with the typical object oriented ,just using fstream
>instead of FILE*  vector  instead of char arrays  and so on ,this will give
>more beautiful coding style.
> jeppeter

Hi,

Thank you for your message.
I understand your concerns about using "FILE" instead of "fstream". However,
as long as OO is concerned, I don't agree your point. We all understand that
OO intends to hide the implementation details from users, thus this "FILE"
is only an
implentation details as long as I don't expose it to my class-users.
As you know, the "fstream" is inhereted from "iostream" and its purpose is
to give a uniformal interface for all I/O methods. In other words, they want
you to treat all I/O in a similar way. To achieve this goal, it has a lot of
details to
take care. However, for my CFG-Reader the only purpose is to read from a
file. (If the user want to input from terminal by typing, it will be
regarded as unrealistic because it is complicatedly long and error-prone.
That's the reason for file-input. ) Then why should I use the complicated
"fstream". Besides "fstream" is supposed to check words. And for me, char by
char checking is necessary. So, I choose to use "FILE".

As for vector instead of char[], I am not quite sure. Since I did expose the
string to my user. It is logically to be some user-friendly data structure.
But a wrapper class will easily solve the interface problem, what do you
think?

By the way, where are you? studying or working? How do you find my web site?
By google?
I am happy to find some pals with same interest.

Keep in touch,

Nick Huang/Qingzhe Huang

Unix learning notes:

Here goes the problem...

> Hi,
>
> I loggin to alpha and edit the .cshrc as showed in your slides. But when
> I checked the version of java , it is still 1.4.1 by "java -version". At
> first I thought I have made some mistakes in .cshrc, but I checked and
> cannot find any error in file cshrc. Can you check the file attached for
> me? thank you for your help,

The newer account have two 'set path=' statements: after if() and after
then(). You changed the one for Linux I should think.

Here is the result...

Hi,

Thank you for your message, you are right! I don't understand the "if", so I
change the wrong place. It works now.

have a nice day,

Nick Huang/Qingzhe Huang

How should I change the environment variables?

set env PATH /mypath/ :$PATH

This will add /mypath/ before the old path. And you can also append the path.

The several stupid mistakes when using java first time...

1. The file name must be exactly same as class name. What an absurd request? It is very obvious the JDK writer

is such a lazy, arrogant guy!

2. You must add public before the class. What a meaningless idea? Is there any private class? Possibly yes.

3. Don't forget the class usually starts with capital letter. It is sensable.

This is a little example of callback function.

这个小例子是我们都玩过的剪刀石头布。有一个裁判程序(judge),你和我都有一个出手的程序(youFight, meFight)和以及各自的策略数据(yourStrategy,
myStrategy)。使用的时候就把他们都当作参数带入裁判程序。
为什么要这样写呢?原因就是flexibility,假如,你忽然想要改变策略数据的话,就换一个参数带入就好了,裁判时不用变得。你也可以改变你的出牌的方法
也就是重新定义一个新函数,只要参数类型个数,返回值类型与现在的一样就可以了,比如说,改变shift的值,或者就干脆用随机数等等。
#include <iostream>

using namespace std;

//this is not a program, but a joke...hahha...
const int MatchNumber=10;

//you know what they are, right?
//we all play this little game
enum FightType
{Scissor, Stone, Cloth};

char* typeStr[3]={"Scissor", "Stone", "Cloth"};

//this is the sequence you might play
int yourStrategy[MatchNumber]={2,1,0,2,1,2,0,2,1,1};
//this is the sequence I might play
int myStrategy[MatchNumber]={0,1,2,1,2,1,0,2,1,0};


//this is the match judge, with two your play function and your strategy
//and my function and my strategy
void judge(int (* youPlay)(int* yourParam, int theNumber), int* yourParam, 
			 int (*myPlay)(int* myParam, int theNumber), int* myParam);

//actually this is the function you defined here
int youFight(int* youParam, int index);
//I won't repeat
int meFight(int* myParam, int index);

int main()
{
	judge(youFight, yourStrategy, meFight, myStrategy);
	return 0;
}




void judge(int (* youPlay)(int* theParam, int index), int* yourParam, 
			 int (*myPlay)(int* theParam, int index), int* myParam)
{
	int you, me;
	for (int i=0; i<MatchNumber; i++)
	{
		you=youPlay(yourParam, i);
		me=myPlay(myParam, i);
		cout<<"your type is:"<<typeStr[you]<<endl;
		cout<<"my type is:"<<typeStr[me]<<endl;
		switch (you-me)
		{
			
		case 0:
			
			cout<<"it is a tie on match no."<<i+1<<endl;
			break;
		case 1:
		case -2:
			cout<<"you win on match no. "<<i+1<<endl;
			break;
		case -1:
		case 2:
			cout<<"you lose on match no."<<i+1<<endl;
			break;
		}
	}
}

//you can change your strategy simple by....
int youFight(int* youParam, int index)
{
	//actually you can define any method you imagine
	return yourStrategy[(index+5)%MatchNumber];
}

int meFight(int* myParam, int index)
{
	//by shifting the current strategy, you have a new one
	return myStrategy[(index+2)%MatchNumber];
}


This is the example of template class acting as your callback parameter in template function

#include <iostream>

using namespace std;

//this is not a program, but a joke...hahha...
const int MatchNumber=10;

//you know what they are, right?
//we all play this little game
enum FightType
{Scissor, Stone, Cloth};

char* typeStr[3]={"Scissor", "Stone", "Cloth"};


class YourPlay
{
private:
	static int yourStrategy[MatchNumber];
public:
	static int youFight(int index)
	{
		//actually you can define any method you imagine
		return yourStrategy[(index+5)%MatchNumber];
	}
};

class MyPlay
{
private:
	static int myStrategy[MatchNumber];
public:
	static int meFight(int index)
	{
		//by shifting the current strategy, you have a new one
		return myStrategy[(index+2)%MatchNumber];
	}
};

//the static strategy is initialized here
int YourPlay::yourStrategy[MatchNumber]={2,1,0,2,1,2,0,2,1,1};
int MyPlay::myStrategy[MatchNumber]={0,1,2,1,2,1,0,2,1,0};

//THIS IS THE BUG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//you cannot declare the template function
//compiler don't recognize it!!!
//believe it or not, try declare it as following:
/*
template<class yourPlayClass , class myPlayClass>
void judge();
*/
//and put the implementation below after "MAIN" function
//then you will get memory access error, because 
//what you declared is not implemented!!!!!
template<class yourPlayClass , class myPlayClass>
void judge()
{
	int you, me;
	for (int i=0; i<MatchNumber; i++)
	{
		you=yourPlayClass::youFight(i);
		me=myPlayClass::meFight(i);
		cout<<"your type is:"<<typeStr[you]<<endl;
		cout<<"my type is:"<<typeStr[me]<<endl;
		switch (you-me)
		{
			
		case 0:
			
			cout<<"it is a tie on match no."<<i+1<<endl;
			break;
		case 1:
		case -2:
			cout<<"you win on match no. "<<i+1<<endl;
			break;
		case -1:
		case 2:
			cout<<"you lose on match no."<<i+1<<endl;
			break;
		}
	}
}



int main()
{
	judge<YourPlay, MyPlay>();
	return 0;
}



The bug I want to ask about...
Hi Sir,
The following code defined a friend function which overloads the operator "<<" with "ostream". But compiler cannot reconize it as "friend" function:
#include <iostream>
using namespace std;
class Test
{
 friend ostream& operator<<(ostream& out, const Test& dummy);
private:
 int data;
public:
 Test();
};
int main()
{
 Test T;
 cout<<T;
 return 0;
}
Test::Test()
{
 data=15;
}
//the function is already defined as friend, but compiler is blind.
ostream& operator<<(ostream& out, const Test& dummy)
{
 out<<dummy.data<<endl;//access private member of "Test"
return out;
}
The error message is "error C2248: 'data' : cannot access private member declared in class 'Test'
        d:\program files\microsoft visual studio\myprojects\arena\arena.cpp(9) : see declaration of 'data'"
So, I have to put the definition of "friend" function within the declaration of class as following:
#include <iostream>

using namespace std;

class Test
{
	friend ostream& operator<<(ostream& out, const Test& dummy)		
	{
		out<<dummy.data<<endl;//access private member of "Test"
		return out;
	}

private:
	int data;
public:
	Test();
};

int main()
{
	Test T;
	cout<<T;
	return 0;
}

Test::Test()
{
	data=15;
}

I would be grateful if you have an explanation or solution to this kind of problems.
Thank you for your time.
Nick Huang/Qingzhe Huang

问题:

。。。我现在有一个问题想请教你:计算机网络里面的"距离向量路由算法"的演示软件如何实现啊,希望你帮忙,万分感激 !
回答:
刚听到距离向量路由算法以为是什么神奇的东西,google了一下才知道可能是这么回事。
每个路由器维护一个路由表,这个路由表实际上就是Bellman-ford的最大流的一个图,图利的每个edge的weight应该是连接着响铃两个路由器的距离,我像最简单的就是用到达时间来表示,当然这样问题就变成了最小流的,不过算法还是Bellman-ford的算法,(最土的就是把这些时间t表达为100000-t,这里1000000是一个很大的数就行了,就还是最大流问题了。)
运用Bellman-ford算法可以找出一条最短路径,而这个什么“距离向量路由算法”协议自己规定超过15节点的路径就是不通的路径。应该就是这样的。
我当时学算法的时候曾经想写一个bellman-ford的算法的实现,后来实在是太忙了,再加上这个算法确实有些麻烦,我找到一个伪代码,
http://en.wikipedia.org/wiki/Bellman-Ford_algorithm
不过当我匆匆扫了一眼这个算法,我觉得你没有必要用这个,因为dijkstra的算法也能做到,唯一的不足是要求weight必须为正直,在网络里面,距离当然是正的了,我的意思是路由表里面的路径都是双向的,对吧?(关于网络通讯这些EE的课程我只上过一门入门的课,不是很清楚,)不存在说从A到B可以走,从B到A就不能走的情况,对吧?
如果有什么错误记得告诉我一声,我也可以学习一下。
// Define datatypes for a graph
record vertex {
    list edges
    real distance
    vertex predecessor
}
record edge {
    node source
    node destination
    real weight
}

function BellmanFord(list vertices, list edges, vertex source)
   // This implementation takes in a graph, represented as lists of vertices
   // and edges, and modifies the vertices so that their distance and
   // predecessor attributes store the shortest paths.

   // Step 1: Initialize graph
   for each vertex v in vertices:
       if v is source then v.distance = 0
       else v.distance := infinity
       v.predecessor := null
   
   // Step 2: relax edges repeatedly
   for i from 1 to size(vertices):       
       for each edge uv in edges:
           u := uv.source
           v := uv.destination             // uv is the edge from u to v
           if v.distance > u.distance + uv.weight
               v.distance := u.distance + uv.weight
               v.predecessor := u

   // Step 3: check for negative-weight cycles
   for each edge uv in edges:
       u := uv.source
       v := uv.destination
       if v.distance > u.distance + uv.weight
           error "Graph contains a negative-weight cycle"

            My Service Demo

This is simply a demo of how to run a service. It is extremely simple and the code of service is copy&paste from MSDN. However, as usual if you think everything is that straight forward a monkey can probably do the programming.

1. A service is just a program loaded specifically by OS by implementing a certain "interface". Here I don't really mean the common concept of "interface". What I really mean is that you should implement a function so that OS "starts" your service. In this "startService" routine, you have to register a "handler" function to respond to various "message" or "status" sent by OS. Also you need to do some initialization job for your service. The idea is like COM object factory such that you ask the OS to "instantiate" your service instance for you.

2. The service code is all from MSDN and what troubles me is how to start running my service. It seems MSDN assumes you know that by default since programmer who are dealing with services are usually intermediate level. However, I don't know how to start a service programmatically except in command line we run "net start". Then I asked DC and he is not very sure about it either except that he runs "createService" first. Suddenly it is very clear to me. It is some kind similar to COM where you need a kind of "registery" to register your service except that the service registery is maintained by OS and can only be accessed through "SCManager".

a) First you need to access "Service Control Manager" by "OpenSCmanager".

b) With the handle of SCmanager, you create a service instance by "CreateService" which does the registration job for you. Or you can access an existing service by "OpenService".

c) With the handle of service, you can start service by calling "StartService".

3. If you directly run your service program then you will always get error 1063 which tells you that cannot access SCManager and this puzzles me for a week.

file name: myStartService.cpp (this is the program running service)

#include <windows.h>
#include <stdio.h>
#include <TCHAR.H>

LPCTSTR MyServiceName = _T("myService");
LPCTSTR MyServiceDisplayName = _T("my service display name");
LPCTSTR MyServicePathName = _T("\"F:\\MyProjects\\MyService\\Debug\\MyService.exe\"");


const unsigned int MyServiceOpCodeNumber = 7;

enum MyServiceOpCodeEnum
{
	EnumCreate=0, EnumStart=1,  EnumDelete=2, EnumStop=3, EnumContinue=4, EnumPause=5, EnumQuery=6
};


char* MyServiceOpCodeName[MyServiceOpCodeNumber] = 
{
	"create", "start",  "delete", "stop", "continue", "pause", "query"
};
 


void printServiceStatus(SERVICE_STATUS& status)
{
	printf("[service type]");
	switch (status.dwServiceType)
	{
	case SERVICE_FILE_SYSTEM_DRIVER:
		printf("The service is a file system driver.");
		break;
	case SERVICE_KERNEL_DRIVER:
		printf("The service is a device driver.");
		break;
	case SERVICE_WIN32_OWN_PROCESS:
		printf("The service runs in its own process.");
		break;
	case SERVICE_WIN32_SHARE_PROCESS:
		printf("The service shares a process with other services.");
		break;
	case SERVICE_INTERACTIVE_PROCESS:
		printf("The service can interact with the desktop.");
		break;
	}
	printf("\n");
	printf("[service state]");
	switch (status.dwCurrentState)
	{
	case SERVICE_CONTINUE_PENDING:
		printf("The service continue is pending.");
		break;
	case SERVICE_PAUSE_PENDING:
		printf("The service pause is pending.");
		break;
	case SERVICE_PAUSED:
		printf("The service is paused.");
		break;
	case SERVICE_RUNNING:
		printf("The service is running.");
		break;
	case SERVICE_START_PENDING:
		printf("The service is starting.");
		break;
	case SERVICE_STOP_PENDING:
		printf("The service is stopping.");
		break;
	case SERVICE_STOPPED:
		printf("The service is not running.");
		break;
	}
	printf("\n");
}

BOOL myServiceOperation(MyServiceOpCodeEnum opCode)
{
	SC_HANDLE scHandle  = NULL;
	SC_HANDLE svcHandle = NULL;
	BOOL result = FALSE;
	SERVICE_STATUS serviceStatus;
	if ((scHandle = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS))!=  NULL)
	{
		if (opCode == EnumCreate)
		{
			if ((svcHandle = CreateService(scHandle, MyServiceName, MyServiceDisplayName, SERVICE_ALL_ACCESS, 
				SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, MyServicePathName,
				NULL, NULL, NULL, NULL, _T("202409")))!=NULL)
			{
				result = TRUE;				
			}
		}
		else
		{
			if ((svcHandle = OpenService(scHandle, MyServiceName, SERVICE_ALL_ACCESS))
					!= NULL)
			{	
				switch (opCode)
				{
				case EnumDelete:
					result = DeleteService(svcHandle);						
					break;
				case EnumStart:
					result = StartService(svcHandle, 0, NULL);					
					break;					
				case EnumStop:
					result = ControlService(svcHandle, SERVICE_CONTROL_STOP, &serviceStatus);
					break;
				case EnumPause:
					result = ControlService(svcHandle, SERVICE_CONTROL_PAUSE, &serviceStatus);
					break;
				case EnumContinue:
					result = ControlService(svcHandle, SERVICE_CONTROL_CONTINUE, &serviceStatus);
					break;
				case EnumQuery:
					result = ControlService(svcHandle, SERVICE_CONTROL_INTERROGATE, &serviceStatus);
					break;				
				}
				if (result)
				{
					printServiceStatus(serviceStatus);
				}				
			}
		}
		if (svcHandle != NULL)
		{
			CloseServiceHandle(svcHandle);
		}

		CloseServiceHandle(scHandle);
	}
	else
	{
		_tprintf(_T("error of open sc manager of [%d]\n"), GetLastError());
	}

	return result;
}

int _tmain(int argc, LPTSTR* argv)
{
	int i;
	if (argc != 2)
	{
		_tprintf(_T("usage: "));
		for (i =0 ; i<MyServiceOpCodeNumber; i++)
		{
			_tprintf(_T("[%s]"), MyServiceOpCodeName[i]);
		}
		_tprintf(_T("\n"));
		return 0;
	}
	for (i = 0; i < MyServiceOpCodeNumber; i ++)
	{
		if (_tcsicmp(argv[1], _T(MyServiceOpCodeName[i])) == 0)
		{
			if (myServiceOperation((MyServiceOpCodeEnum)i))
			{
				_tprintf(_T("my service operation %s successful!\n"), MyServiceOpCodeName[i]);
			}
		}
	}
	return 0;
}

	

file name: myservice.cpp (This is your service which can also accept "command parameter" passed by SCManager when you try to start your service.)

#include <windows.h>
#include <stdio.h>
#include <TCHAR.h>

SERVICE_STATUS          MyServiceStatus; 
SERVICE_STATUS_HANDLE   MyServiceStatusHandle; 
 
VOID __stdcall  MyServiceStart (DWORD argc, LPTSTR *argv); 
VOID __stdcall MyServiceCtrlHandler (DWORD opcode); 
DWORD MyServiceInitialization (DWORD argc, LPTSTR *argv, 
        DWORD *specificError); 
VOID SvcDebugOut(LPSTR String, DWORD Status);

 
LPCTSTR MyServiceName = _T("myService");
LPCTSTR MyServiceDisplayName = _T("my service display name");
LPCTSTR MyServicePathName = _T("\"F:\\MyProjects\\MyService\\Debug\\MyService.exe\"");


/*
int test()
{
	char buffer[2024];
	SC_HANDLE scHandle = NULL;
	ENUM_SERVICE_STATUS_PROCESS* pEnumStatus;
	DWORD bytesNeeded = 0;
	DWORD entryReturned = 0;
	DWORD resumeHandle = 0;
	DWORD err;

	if ((scHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS|GENERIC_READ)) == NULL)
	{
		printf("error of [%d]\n", GetLastError());
		return 1;
	}
	pEnumStatus = (LPENUM_SERVICE_STATUS_PROCESS)buffer;


	while (true)
	{
		if (!EnumServicesStatusEx(scHandle, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, 
			pEnumStatus, 2024, &bytesNeeded, &entryReturned, &resumeHandle,	NULL))
		{
			err = GetLastError();
			if ( err !=  ERROR_MORE_DATA)
			{
				printf("unknown error %u\n", err);
				break;
			}
		}
		else
		{
			printf("entry returned %d\n", entryReturned);
			_tprintf(_T("servicename[%s]displayname[%s]\n"), pEnumStatus->lpServiceName,
				pEnumStatus->lpDisplayName);
		}
	}

	return 0;
}
*/



void main( ) 
{ 
    SERVICE_TABLE_ENTRY   DispatchTable[2];
	
	DispatchTable[0].lpServiceName = "MyService";
	DispatchTable[0].lpServiceProc = MyServiceStart;
	DispatchTable[1].lpServiceName = NULL;
	DispatchTable[1].lpServiceProc = NULL;

    
    if (!StartServiceCtrlDispatcher( DispatchTable)) 
    { 
        SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher error = %d\n", GetLastError()); 
    } 
} 
 
VOID SvcDebugOut(LPSTR String, DWORD Status) 
{ 
    CHAR  Buffer[1024]; 
    if (strlen(String) < 1000) 
    { 
        sprintf(Buffer, String, Status); 
        OutputDebugString(Buffer); 
    } 
} 



VOID __stdcall MyServiceCtrlHandler (DWORD Opcode) 
{ 
    DWORD status; 
 
    switch(Opcode) 
    { 
        case SERVICE_CONTROL_PAUSE: 
        // Do whatever it takes to pause here. 
            MyServiceStatus.dwCurrentState = SERVICE_PAUSED; 
            break; 
 
        case SERVICE_CONTROL_CONTINUE: 
        // Do whatever it takes to continue here. 
            MyServiceStatus.dwCurrentState = SERVICE_RUNNING; 
            break; 
 
        case SERVICE_CONTROL_STOP: 
        // Do whatever it takes to stop here. 
            MyServiceStatus.dwWin32ExitCode = 0; 
            MyServiceStatus.dwCurrentState  = SERVICE_STOPPED; 
            MyServiceStatus.dwCheckPoint    = 0; 
            MyServiceStatus.dwWaitHint      = 0; 
 
            if (!SetServiceStatus (MyServiceStatusHandle, 
                &MyServiceStatus))
            { 
                status = GetLastError(); 
                SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld\n",status); 
            } 
 
            SvcDebugOut(" [MY_SERVICE] Leaving MyService \n",0); 
            return; 
 
        case SERVICE_CONTROL_INTERROGATE: 
        // Fall through to send current status. 
            break; 
 
        default: 
            SvcDebugOut(" [MY_SERVICE] Unrecognized opcode %ld\n", 
                Opcode); 
    } 
 
    // Send current status. 
    if (!SetServiceStatus (MyServiceStatusHandle,  &MyServiceStatus)) 
    { 
        status = GetLastError(); 
        SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld\n",status); 
    } 
} 


void __stdcall MyServiceStart (DWORD argc, LPTSTR *argv) 
{ 
    DWORD status; 
    DWORD specificError; 
 
    MyServiceStatus.dwServiceType        = SERVICE_WIN32; 
    MyServiceStatus.dwCurrentState       = SERVICE_START_PENDING; 
    MyServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | 
        SERVICE_ACCEPT_PAUSE_CONTINUE; 
    MyServiceStatus.dwWin32ExitCode      = 0; 
    MyServiceStatus.dwServiceSpecificExitCode = 0; 
    MyServiceStatus.dwCheckPoint         = 0; 
    MyServiceStatus.dwWaitHint           = 0; 
 
    MyServiceStatusHandle = RegisterServiceCtrlHandler( 
        "MyService", 
        MyServiceCtrlHandler); 
 
    if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) 
    { 
        SvcDebugOut(" [MY_SERVICE] RegisterServiceCtrlHandler failed %d\n", GetLastError()); 
        return; 
    } 
 
    // Initialization code goes here. 
    status = MyServiceInitialization(argc,argv, &specificError); 
 
    // Handle error condition 
    if (status != NO_ERROR) 
    { 
        MyServiceStatus.dwCurrentState       = SERVICE_STOPPED; 
        MyServiceStatus.dwCheckPoint         = 0; 
        MyServiceStatus.dwWaitHint           = 0; 
        MyServiceStatus.dwWin32ExitCode      = status; 
        MyServiceStatus.dwServiceSpecificExitCode = specificError; 
 
        SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus); 
        return; 
    } 
 
    // Initialization complete - report running status. 
    MyServiceStatus.dwCurrentState       = SERVICE_RUNNING; 
    MyServiceStatus.dwCheckPoint         = 0; 
    MyServiceStatus.dwWaitHint           = 0; 
 
    if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus)) 
    { 
        status = GetLastError(); 
        SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld\n",status); 
    } 
 
    // This is where the service does its work. 
    SvcDebugOut(" [MY_SERVICE] Returning the Main Thread \n",0); 
 
    return; 
} 
 
// Stub initialization function. 
DWORD MyServiceInitialization(DWORD   argc, LPTSTR  *argv, 
    DWORD *specificError) 
{ 
    argv; 
    argc; 
    specificError; 
    return(0); 
} 

        This is a list copied from CSDN


Windows2000可执行文件一览(一)

(未完,待续)

文件名称

简介

accwiz.exe

辅助功能向导

append.exe

打开指定文件夹中的数据文件

arp.exe

显示和修改“地址解析协议”(ARP) 所使用的到以太网的 IP 或令牌环物理地址翻译表

at.exe

列出在指定的时间和日期在计算机上运行的已计划命令或计划命令和程序

atmadm.exe

ATM 呼叫管理器在异步传输模式 (ATM) 网络上注册的监视器连接和地址

attrib.exe

显示或更改文件属性

cacls.exe

显示或修改文件的访问控制列表 (ACL)。

calc.exe

计算器

cdplayer.exe

CD唱机

charmap.exe

字符映射表

chkdsk.exe

基于所用的文件系统,创建和显示磁盘的状态报告

chkntfs.exe

显示或指定在启动计算机时计划的自动系统检查是否在 FAT、FAT32 或者 NTFS 卷上运行

chnuconv.exe

中文转码器

cipher.exe

NTFS 卷上显示或改变文件的加密

cjime.exe

微軟新倉頡輸入法 98a 安装包

cleanmgr.exe

磁盘清理程序

cliconfg.exe

SQL Server 客户端网络工具

clipbrd.exe

剪切板察看工具

clipsrv.exe

DDE 服务程序

cluster.exe

群集管理器

conf.exe

NetMeeting 程序

control.exe

控制面板

convert.exe

FAT 或 FAT32 卷转换成 NTFS 卷。不能转换当前驱动器。如果 convert 不能锁定驱动器,则将在下一次重新启动计算机时转换该驱动器

dcomcnfg.exe

分布式 COM配置属性

dcpromo.exe

活动目录安装向导

ddeshare.exe

DDE 共享器

debug.exe

测试和调试 MS-DOS 可执行文件的程序

dialer.exe

电话拨号程序

diskperf.exe

控制计数器的类型,这些计数器可以用系统监视器查看

doskey.exe

撤回 Windows 2000 命令、编辑命令行和创建宏。

drwatson.exe

系统错误诊断工具

drwtsn32.exe

系统错误诊断工具

dvdplay.exe

DVD播放机

dxdiag.exe

DirectX诊断工具

edlin.exe

创建和更改 ASCII 文件的、面向行的文本编辑器

eudcedit.exe

造字程序

eventvwr.exe

事件查看器

evntcmd.exe

显示 SNMP 事件

exe2bin.exe

将可执行文件 (.exe) 转换成二进制格式

expand.exe

展开一个或多个压缩文件。该命令用于从发行磁盘中提取压缩文件

explorer.exe

资源管理器

fastopen.exe

Windows 2000 和 MS-DOS 子系统不使用该命令。它被接受只是因为和 MS-DOS 文件兼容

faxcover.exe

传真封面编辑程序

faxqueue.exe

传真机队列管理器

faxsend.exe

传真发送程序

fc.exe

比较两个文件并显示它们之间的差异

find.exe

在一个文件或多个文件中搜索指定的文本字符串

findstr.exe

使用文字文本或常规表达式搜索文件中的字符串

finger.exe

在运行 Finger 服务的指定系统上显示有关用户的信息

forcedos.exe

启动 MS-DOS 子系统中指定的程序

fp98swin.exe

FrontPage 服务器管理程序

freecell.exe

空当接龙游戏

ftp.exe

将文件传送到正在运行 FTP 服务的远程计算机或从正在运行 FTP 服务的远程计算机传送文件(有时称作 daemon)。

help.exe

提供关于 Windows 2000 命令(非网络)的联机信息

hh.exe

chm帮助文件服务程序

hostname.exe

打印当前计算机(主机)的名称

icwconn1.exe

Internet连接向导

icwconn2.exe

Internet连接向导

ieshwiz.exe

自定义文件夹向导

iexplore.exe

IE浏览器

imegen.exe

输入法生成器 属性程序

inetmgr.exe

Internet信息服务管理程序

inetwiz.exe

Internet连接向导

internat.exe

输入法托盘显示器

ipconfig.exe

显示所有当前的 TCP/IP 网络配置值

ipsecmon.exe

IP安全监视器

ipxroute.exe

显示和修改有关由 IPX 协议使用的路由表的信息

irftp.exe

通过红外链接发送文件

label.exe

创建、修改或删除磁盘的卷标(名称)。

lcwiz.exe

许可证符合向导

licmgr.exe

企业授权程序(许可证)

lpq.exe

获取运行 LPD 服务器的计算机上打印队列的状态。

lpr.exe

将文件打印到运行 LPD 服务器的计算机。

magnify.exe

放大镜程序

mmc.exe

控制台程序

mobsync.exe

同步程序

mountvol.exe

创建、删除或列出卷的装入点

mplay32.exe

媒体播放机

mplayer2.exe

媒体播放机

mqmig.exe

消息队列

msimn.exe

OutLook 邮件程序

msinfo32.exe

系统信息查看器

mspaint.exe

画图程序

narrator.exe

语音讲解程序/针对视力不佳的人

nbtstat.exe

使用 NBT(TCP/IP 上的 NetBIOS)显示协议统计和当前 TCP/IP 连接

net.exe

Windows 2000网络命令工具

netsh.exe

配置和监控 Windows 2000 命令行脚本接口

netstat.exe

显示协议统计和当前的 TCP/IP 网络连接

nlsfunc.exe

加载特定国家(地区)的信息

notepad.exe

记事本

nslookup.exe

显示来自域名系统 (DNS) 名称服务器的信息

ntbackup.exe

备份工具

ntbooks.exe

2000帮助

odbcad32.exe

ODBC数据库管理器

osk.exe

Windows 屏幕键盘

packager.exe

对象包装器

pathping.exe

该路由跟踪命令结合了 pingtracert 命令的功能,可提供这两个命令都无法提供附加信息

pax.exe

启动便携式存档互换 (Pax) 实用程序

pentnt.exe

检测 Pentium 芯片中的浮点除法错误(如果存在),禁用浮点硬件并打开浮点仿真。

perfmon.exe

性能日志监视器

pinball.exe

桌上弹球游戏

ping.exe

验证与远程计算机的连接

pintlphr.exe

微软拼音输入法用户造词工具

pintsetp.exe

微软拼音输入法安装向导

poledit.exe

系统策略编辑器

print.exe

打印文本文件或显示打印队列的内容

progman.exe

程序管理器          (一)

标题     Windows2000可执行文件一览(二)    easyxu(原作)
关键字     win2000

文件名称

简介 (续)

progman.exe

程序管理器

rasadmin.exe

远程访问管理器

rasphone.exe

网络连接向导,拨号连接

rcp.exe

Windows 2000 计算机和运行远程外壳端口监控程序 rshd 的系统之间复制文件

recover.exe

从坏的或有缺陷的磁盘中恢复可读取的信息

regedit.exe

注册表编辑器

regedt32.exe

注册表编辑器

replace.exe

用源目录中的同名文件替换目标目录中的文件

rexec.exe

在运行 REXEC 服务的远程计算机上运行命令,在执行指定命令前,验证远程计算机上的用户名

route.exe

控制网络路由表

rsh.exe

在运行 RSH 服务的远程计算机上运行命令

runas.exe

允许用户用其他权限运行指定的工具和程序,而不是用户当前登录提供的权限

share.exe

Windows 2000 和 MS-DOS 子系统不使用该命令

shrpubw.exe

创建共享文件夹工具

sigverif.exe

签字验证工具

sndrec32.exe

声音录音机

sndvol32.exe

音量控制器

sol.exe

纸牌游戏

sort.exe

读取输入、排序数据并将结果写到屏幕、文件和其他设备上

srvmgr.exe

服务器管理器

subst.exe

将路径与驱动器盘符关联

sysedit.exe

系统配置管理器(类似regedit)

syskey.exe

账户数据库加密工具

sysocmgr.exe

Windows2000安装程序

taskmgr.exe

任务管理器

tcmsetup.exe

设置电话客户使用 tcmsetup 指定电话客户使用的远程服务器或禁用客户

tftp.exe

将文件传输到正在运行 TFTP 服务的远程计算机或从正在运行 TFTP 服务的远程计算机传输文件

themes.exe

桌面主题工具

tracert.exe

路由分析诊断程序,将包含不同生存时间 (TTL) 值的 Internet 控制消息协议 (ICMP) 回显数据包发送到目标,以决定到达目标采用的路由

tsadmin.exe

终端服务管理器

usrmgr.exe

域用户管理器

verifier.exe

驱动验证工具

wab.exe

通讯本管理程序

wabmig.exe

通讯本导入工具

wbemperm.exe

权限编辑器

winchat.exe

聊天工具

WINDBVER.EXE

SQL Server 客户端配置工具

winhelp.exe

帮助服务程序 hlp格式

winhlp32.exe

帮助服务程序 hlp格式

winmine.exe

扫雷游戏

winrep.exe

Windows报告工具 D版别用)

winver.exe

显示当前系统的版本号

wizmgr.exe

管理向导

write.exe

写字板程序

wscript.exe

Windows脚本宿主设置

wupdmgr.exe

Windows 更新程序

xcopy.exe

将文件复制到当前目录

Assoc

显示或修改文件名扩展关联

Chcp

显示活动控制台代码页的号码,或者更改 Windows 2000 将用于控制台的活动控制台代码页       (二)(完)


        The following code snippet is just a demo of full-screen window.

The bmp has some size limits for windows cause somebody says windows uses graphic card memory for bitmap.

///////////////////////////////////////////////////////////////////////////////////////////////////
LRESULT WINAPI BackGroundWindowProc(
  HWND hWnd,      // handle to window
  UINT Msg,       // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
)
{
   HDC hdc;
   HDC memDC;
   BITMAP bmp;
   HBITMAP hOldBmp;
   PAINTSTRUCT ps;
   switch (Msg)
   {
   case WM_DESTROY: 
  PostQuitMessage(0);
  break;
    
   case WM_ERASEBKGND:
        return 1;


#if 0
   case WM_PAINT:
      //draw bitmap
      if (hBackGroundBmp != NULL) {
         if ((hdc = GetWindowDC(hWnd))!= NULL){
            if ((memDC = CreateCompatibleDC(hdc))!= NULL){
               if (GetObject(hBackGroundBmp, sizeof(BITMAP), &bmp)){
                  hOldBmp = (HBITMAP)SelectObject(memDC, hBackGroundBmp);
                  StretchBlt(hdc, 0, 0, width, height, memDC, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
                  SelectObject(memDC, hOldBmp);
               }
               DeleteDC(memDC);
            }
            ReleaseDC(hWnd, hdc);
         }
      }     
      break;
#else
  case WM_PAINT:
      //draw bitmap
     
      if (hBackGroundBmp != NULL) {
         if ((hdc = BeginPaint(hWnd, &ps))!= NULL){
            if ((memDC = CreateCompatibleDC(hdc))!= NULL){
               if (GetObject(hBackGroundBmp, sizeof(BITMAP), &bmp)){
                  hOldBmp = (HBITMAP)SelectObject(memDC, hBackGroundBmp);
                  StretchBlt(hdc, 0, 0, width, height, memDC, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
                  SelectObject(memDC, hOldBmp);
               }
               DeleteDC(memDC);
            }
            EndPaint(hWnd, &ps);
         }
      }
     
      break;
#endif
   default:
         return DefWindowProc(hWnd, Msg, wParam, lParam);
   }
   return 0L;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CPrintstikInstallerApp::CreateBackGroundWindow()
{
static LPCWSTR WindowName              = _T("BackGround");
static LPCWSTR BackGroundImageFileName = _T("res\\printstik_install_window5.bmp");

 memset(&wndClass, 0, sizeof(WNDCLASSEX));
 wndClass.cbSize        = sizeof(WNDCLASSEX);
 width                  = GetSystemMetrics(SM_CXSCREEN);
 height                 = GetSystemMetrics(SM_CYSCREEN);
 wndClass.hInstance     =  m_hInstance;
 wndClass.lpszClassName = WindowName;
 wndClass.lpfnWndProc   = BackGroundWindowProc;
#if 1
   if ((hBackGroundBmp    = (HBITMAP)LoadImage(m_hInstance, BackGroundImageFileName, IMAGE_BITMAP, 0, 0,
      LR_LOADFROMFILE))   == NULL){
      int err = GetLastError();
      return FALSE;
   }
#else
   if ((hBackGroundBmp    = (HBITMAP)LoadBitmap(m_hInstance, MAKEINTRESOURCE(IDB_BACKGROUND))) == NULL){
      int err = GetLastError();
      return FALSE;
   }
#endif

 if (Not RegisterClassEx(&wndClass))
 {
  return FALSE;
 }

 if ((HBackGroundWnd = CreateWindow(WindowName, NULL, WS_BORDER, 0, 0, width, height, NULL, NULL,
      m_hInstance, NULL)) == NULL){
      return FALSE;
   }

   if (HBackGroundWnd != NULL){
    ShowWindow(HBackGroundWnd, SW_SHOW);

    UpdateWindow(HBackGroundWnd); 
   }

   return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

This is a basic story. When you want to delete a registery, open its upper key, and then call regdeletevalue, instead of regdeletekey. This is a common error for people like me to confuse with key and value.
Remember, the first parameter cannot be the predefined "handle" of key like  HK_LOCAL_MACHINE.
When you create a directory, check if it is already existed with "GetFileAtrribute".
DC asks me if I know how to install a device and I know he is going to give some tricks and answer simply NO. Then he begin to tell me a simple tip that special device with composite drivers should NOT be connected before drivers are installed. This maybe true if you don't handle driver installer properly.
The background must have a tab order #1 in order to show all other buttons etc.
I finally find what I want! In vc6, by pressing ctrl+F4, you can navigate forward and backward.

            A small function to fix size error of bitmap file.(downloaded bmp file often has such problems.)

bool repairBmp(LPCTSTR fileName)
{
	bool bRet = false;
	HANDLE handle;
	DWORD  imageSize;
	BITMAPFILEHEADER bfh;
	BITMAPINFOHEADER bih;
	DWORD  newImageSize, bytesRead;
	int widthInBytes, newHeight;
	if ((handle = CreateFile(fileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL,
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)
	{
		if (ReadFile(handle, &bfh, sizeof(BITMAPFILEHEADER), &bytesRead, NULL))
		{
			if (ReadFile(handle, &bih, sizeof(BITMAPINFOHEADER), &bytesRead, NULL))
			{
				if ((imageSize = GetFileSize(handle, NULL)) != INVALID_FILE_SIZE)
				{					
					if (bfh.bfSize != imageSize && bih.biBitCount == 24)
					{
						widthInBytes = (bih.biWidth*3 + 3)&(~3);
						newHeight = (imageSize - sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER))/ widthInBytes;
						newImageSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + widthInBytes * newHeight;						
							
						bfh.bfSize = newImageSize;
						bih.biHeight = newHeight;
						if (SetFilePointer(handle, 0, NULL, FILE_BEGIN)!= INVALID_SET_FILE_POINTER)
						{
							if (WriteFile(handle, &bfh, sizeof(BITMAPFILEHEADER), &bytesRead, NULL))
							{
								if (WriteFile(handle, &bih, sizeof(BITMAPINFOHEADER), &bytesRead, NULL))
								{
									if (SetFilePointer(handle, newImageSize, NULL, FILE_BEGIN)!= INVALID_SET_FILE_POINTER)
									{
										if (SetEndOfFile(handle))
										{
											bRet = true;
										}
									}
								}
							}
						}
					}
				}
			}
		}
		CloseHandle(handle);
	}
	return bRet;
}
		

   

                                                       back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)