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
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。 A∪B
= { 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?
这个问题解决了:问朱春明同学,他说的很好,我们就取最长的指令好了,有什么关系?反正纪录的是下一条指令的首地
址。好!
问题:
您好!有个加密问题想请教您,比如rijindael 是256bit 加密的,如果我的password是8位或100位,是否破解时间一样(用穷举法)。这里所指的258bit是怎样一种概念,是否最长password为256位。
我的解答:
逻辑仅仅是征途上的航标灯???
假如给我们一棵搜索树,每个节点代表一个逻辑判断,从一个已知真伪的节点出发根据一系列的所谓“逻辑”关系去试图到达某一个目的节点,这个过程我们通常称作“逻辑推理”。从广义的搜索来看,逻辑的与或仅仅是节点之间相对关系。
例如,所谓“或”说的是当你到达某一个节点继续前进有一系列子节点供选择时候,从“或”中任意选一个都可以继续。
所谓“与”说的是当你达到某一个节点继续前进有一系列子节点供选择时候,必须要同时选择这些子节点才可以继续前进,可是,我们真的有“分身术”同时走多个路径吗?
这其中似乎蕴含着某种深奥的东西,绝非“串联,并联”这么肤浅。
我在想也许几百年后的考古学家都是计算机,他们所感兴趣的课题就是人类的思想发展,那么我的这些日记加垃圾就是一份极好的素材。
问题:
回答:
真正的问题:
在我心目中基本上任何问题都可以用一个搜索来解决,只是搜索的级别不同,或者说层面,这个意思不好表达,比如我们有一个函数,我们让他去解决一个问题,可是当我们有很多的函数解决具体的问题,我们需要一个更高级的函数来调用这一系列函数来解决一个更高级的问题,这就是high-order-function的意思。而所有的搜索都是基于一个有根的树,这一点不妨用自动机的角度来看,我们可以有很多的或者根本没有final state,可是不能没有起始点,而且只能有一个。这一点从数据结构的角度来看,我们不允许重复,因为,有环的搜索只会陷入死循环。树的定义就是没有环的图。
问题是我们找不到起始点,或者说有无限或者说有很多的可能的起始点的话,我们的搜索会变得不可行,这才是问题!
>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...
#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; }
问题: 。。。我现在有一个问题想请教你:计算机网络里面的"距离向量路由算法"的演示软件如何实现啊,希望你帮忙,万分感激 !
回答:
// 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"
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
|
|
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.
#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::
{
static LPCWSTR WindowName = _T("BackGround");
static LPCWSTR BackGroundImageFileName = _T("res\\printstik_install_
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_
LR_LOADFROMFILE)) == NULL){
int err = GetLastError();
return FALSE;
}
#else
if ((hBackGroundBmp = (HBITMAP)LoadBitmap(m_
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;
}
//////////////////////////////
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; }