1.30å²å¦javaå¯ä»¥å
2.javaå¦ä¹ å¿å¾
3.MFC中的扒皮扒皮InitInstance()函数应该怎样理解
30å²å¦javaå¯ä»¥å
å²å¯ä»¥å¦javaï¼ä¸ä¼å¾æãJavaæ¯ä¸é¨é¢å对象ç¼ç¨è¯è¨ï¼ä¸ä» å¸æ¶äºC++è¯è¨çåç§ä¼ç¹ï¼è¿æå¼äºC++éé¾ä»¥ç解çå¤ç»§æ¿ãæéçæ¦å¿µï¼å æ¤Javaè¯è¨å ·æåè½å¼ºå¤§åç®åæç¨ä¸¤ä¸ªç¹å¾ãJavaè¯è¨ä½ä¸ºéæé¢å对象ç¼ç¨è¯è¨ç代表ï¼æ好å°å®ç°äºé¢å对象ç论ï¼å 许ç¨åºå以ä¼é çæç»´æ¹å¼è¿è¡å¤æçç¼ç¨ã
Javaå ·æç®åæ§ãé¢å对象ãåå¸å¼ãå¥å£®æ§ãå®å ¨æ§ãå¹³å°ç¬ç«ä¸å¯ç§»æ¤æ§ãå¤çº¿ç¨ãå¨ææ§çç¹ç¹ãJavaå¯ä»¥ç¼åæ¡é¢åºç¨ç¨åºãWebåºç¨ç¨åºãåå¸å¼ç³»ç»ååµå ¥å¼ç³»ç»åºç¨ç¨åºçã
ç¼ç¨å·¥å ·ï¼
Eclipseï¼ä¸ä¸ªå¼æ¾æºä»£ç çãåºäºJavaçå¯æ©å±å¼åå¹³å°ã
NetBeansï¼å¼æ¾æºç çJavaéæå¼åç¯å¢ï¼éç¨äºåç§å®¢æ·æºåWebåºç¨ã
IntelliJ IDEAï¼å¨ä»£ç èªå¨æ示ã代ç åæçæ¹é¢çå ·æå¾å¥½çåè½ã
MyEclipseï¼ç±Genuitecå ¬å¸å¼åçä¸æ¬¾åä¸å软件ï¼æ¯åºç¨æ¯è¾å¹¿æ³çJavaåºç¨ç¨åºéæå¼åç¯å¢ã
EditPlusï¼å¦ææ£ç¡®é ç½®Javaçç¼è¯å¨âJavacâ以å解éå¨âJavaâåï¼å¯ç´æ¥ä½¿ç¨EditPlusç¼è¯æ§è¡Javaç¨åºã
javaå¦ä¹ å¿å¾
Javaå¦ä¹ å¿å¾
å¼è¨
软件å¼åä¹è·¯æ¯å 满èæ£ä¸ææä¹è·¯,ä¹æ¯å 满å¸æä¹è·¯ãJavaå¦ä¹ ä¹æ¯å¦æ¤ï¼æ²¡ææ·å¾å¯èµ°ã梦æ³åã天é¾å «é¨ãä¸è竹ä¸æ ·è¢«æ å´åééç顶èè½»æ¾è·å¾ä¸ç²åååï¼æ¯å¾ä¸ç°å®çãæ¯å¤©ä»°å¤©å¤§å«"天ç¥åï¼è¯·èµç»æä¸æ¬èµè±å®å ¸å§"ï¼æ®ä¸ç¥å³ä½¿ä½ è·å¾äºèµè±å®å ¸ï¼é¤äºåèªå®«å ¶èº«ä¹è¦å¤ï¼ä½ ä¹ä¸ä¸å®æå¾äº"ä¸æ¹ä¸è´¥"ï¼åæ¯æ"西æ¹å¤±è´¥"çå çé«ä¸ç¹ã
"ä¸èµ°å¼¯è·¯ï¼å°±æ¯æ·å¾"ï¼ä½ç»è¯´çä¸æ éçã
1ï¼å¦ä½å¦ä¹ ç¨åºè®¾è®¡ï¼
Javaæ¯ä¸ç§å¹³å°ï¼ä¹æ¯ä¸ç§ç¨åºè®¾è®¡è¯è¨ï¼å¦ä½å¦å¥½ç¨åºè®¾è®¡ä¸ä» ä» éç¨äºJavaï¼å¯¹C++çå ¶ä»ç¨åºè®¾è®¡è¯è¨ä¹ä¸æ ·ç®¡ç¨ãæç¼ç¨é«æ认为ï¼Javaä¹å¥½Cä¹å¥½æ²¡ä»ä¹åå«ï¼æ¿æ¥å°±ç¨ã为ä»ä¹ä»ä»¬è½è¾¾å°å¦æ¤å¢çï¼ææ³æ¯å 为ç¼ç¨è¯è¨ä¹é´æå ±éä¹å¤ï¼é¢ä¼äºç¼ç¨çç²¾é«ï¼èªç¶è½å¤åå°ä¸éç¾éãå¦ä½å¦ä¹ ç¨åºè®¾è®¡çæå½ç¶ä¹æ许å¤å ±éçå°æ¹ã
1.1ãå¹å »å ´è¶£
å ´è¶£æ¯è½å¤è®©ä½ åæä¸å»çå¨åãå¦æåªæ¯æåç¨åºä½ä¸ºè°ççæ段çè¯ï¼ä½ ä¼æ´»çå¾ç´¯ï¼ä¹å¤ªå¯¹ä¸èµ·èªå·±äºãå¤å ³å¿ä¸äºè¡ä¸è¶£äºï¼å¤æ³æ³çè¨ãä¸æ¯æå¡å¤©å¤©åç½æ¥æ¢¦ï¼ä½äººè¦æ¯æ²¡æäºæ¢¦æ³ï¼ä½ è§å¾æå³éåï¼å¯è½å许å¤æ·±å³æ¬å°åæ°ä¸æ ·ï¼ææ麻å°ï¼ååå夫è¶ï¼ææè´¢ç¥ç·ï¼æ¯ä¸ªæå°±æå ä¸åå ä¸çè³æ´å¤çè¿å¸ï¼å空å¤åºä¸ª"é£å©é¶å±"ãä½ è®¤ä¸ºï¼è¿æ ·æå³éåï¼æ空å¤å°ä¸äºç¨åºå论å转转ï¼ä½ ä¼åç°ï¼ä»ä»¬å ¶å®å¾ä¹è§å¹½é»ï¼æ¶ä¸æ¶ä¼ååºæºæ §çç«è±ã
1.2ãæ éç¨åºè®¾è®¡è¯è¨
ç·æå ¥éè¡ï¼å¥³æå«ééãåå¦è éæ©ç¨åºè®¾è®¡è¯è¨éè¦è°¨æ å¯¹å¾ ã软件å¼åä¸ä» ä» æ¯ææ¡ä¸é¨ç¼ç¨è¯è¨äºäºï¼å®è¿éè¦å ¶ä»å¾å¤æ¹é¢çèæ¯ç¥è¯ã软件å¼åä¹ä¸ä» ä» å±éäºæå 个é¢åï¼èæ¯å·²ç»æ¸éå°äºåè¡åä¸å ä¹æ¯ä¸ä¸ªè§è½ã
å¦æä½ å¯¹ç¡¬ä»¶æ¯è¾æå ´è¶£ï¼ä½ å¯ä»¥å¦ä¹ Cè¯è¨/æ±ç¼è¯è¨ï¼è¿å ¥ç¡¬ä»¶å¼åé¢åãå¦æä½ å¯¹çµä¿¡çè¡ä¸ç¥è¯åç½ç»æ¯è¾çæï¼ä½ å¯ä»¥å¨C/C++çä¹ä¸å¤è±æ¶é´ï¼ä»¥æè¿å ¥çµä¿¡è½¯ä»¶å¼åé¢åãå¦æä½ å¯¹æä½ç³»ç»æ¯è¾çæï¼ä½ å¯ä»¥å¦ä¹ C/Linuxçç,为Linuxå æ ¸å¼å/驱å¨ç¨åºå¼å/åµå ¥å¼å¼åæåºç¡ã
å¦æä½ æ³ä»å ¥å°åºç¨èå´æ广æ³çåºç¨è½¯ä»¶å¼åï¼å æ¬çµååå¡çµåæ¿å¡ç³»ç»ï¼çè¯ï¼ä½ å¯ä»¥éæ©J2EEæ.NETï¼çè³LAMPç»åãæ¯ä¸ªé¢åè¦æ±çèæ¯ç¥è¯ä¸ä¸æ ·ãååºç¨è½¯ä»¶éè¦å¯¹æ°æ®åºçå¾çæãæ»ä¹ï¼ä½ éè¦æ ¹æ®èªå·±çç¹ç¹æ¥éæ©åéä½ çç¼ç¨è¯è¨ã
1.3ãè¦èè¸å®å°,å¿«é¤å¼çå¦ä¹ ä¸å¯å
å å享ä¸ä¸ªæ äºã
æä¸ä¸ªå°æåï¼ä»å¾å欢ç 究çç©å¦ï¼å¾æ³ç¥éé£äºè´è¶å¦ä½ä»è¹å£³éåºæ¥ï¼åæè´è¶ä¾¿ä¼é£ãæä¸æ¬¡ï¼ä»èµ°å°èåä¸é¢çè§ä¸ä¸ªè¹ï¼ä¾¿åäºå家ï¼ç¶åççï¼è¿äºå 天以åï¼è¿ä¸ªè¹åºäºä¸æ¡è£çï¼çè§éé¢çè´è¶å¼å§æ£æï¼æ³æç ´è¹å£³é£åºæ¥ãè¿ä¸ªè¿ç¨è¾¾æ°å°æ¶ä¹ä¹ ï¼è´è¶å¨è¹éé¢å¾è¾è¦å°æ¼å½æ£æï¼æä¹ä¹æ²¡æ³åèµ°åºæ¥ãè¿ä¸ªå°å©ççççä¸å¿å¿ï¼å°±æ³ä¸å¦è®©æ帮帮å®å§ï¼ä¾¿éææ¿èµ·åªåå¨è¹ä¸åªå¼ï¼ä½¿è´è¶ç ´è¹èåºãä½è´è¶åºæ¥ä»¥åï¼å ä¸ºç¿ èä¸å¤åï¼åå¾å¾èè¿ï¼é£ä¸èµ·æ¥ã
è¿ä¸ªæ äºç»æ们çå¯ç¤ºæ¯ï¼æ¬²éåä¸è¾¾ã
æµ®èºæ¯ç°ä»£äººææ®éçå¿æï¼è½æªè°ï¼ä¹è®¸æ¯è´«ç©·è½åäºè¿ä¹å¤å¹´çç¼æ ï¼å°±åå½å¹´ç大è·è¿ä¸æ ·ï¼é½æ³å¤§æ¥è·¨å ¥***主ä¹ç¤¾ä¼ãç°å¨çè½¯ä»¶å ¬å¸ã客æ·ãæ¿åºãå¦æ ¡ãå¹è®æºæççå°å¤å¼¥æ¼«çæµ®èºä¹æ°ãå°±æ¿ææ¯è¾çæç大è¿å¤§å·¥ITèä¸å¹è®æ¥è¯´å§ï¼å± ç¶æ广å宣称"å¤å¹´ç计ç®æºèä¸æè²ï¼è¾½å®çåä½³å¦æ ¡"ï¼æ®ä¸ç¥ä¸å½è®¡ç®æºåå±æå å¹´ï¼è½¯ä»¶åå±æå å¹´ï¼å± ç¶å»æ¥åçå¦çä¸å°ï¼ç®ç´æ¯èè§å¤©ä¸ç¨åºåãå¹è®åºæ¥çâç¨åºåâ大å¤ä¸ç¥éOO,OP为ä½ç©ï¼ç¤¾ä¼ç¯å¢å¦æ¯ï¼æ们ä¸è½æ¹åï¼åªè½æ¹åèªå·±,é¹å¸ä¸çå®å®ï¼å¼¥è¶³çè´µã许å¤åå¦è C++/Java没å¼å§å¦ï¼ç«é©¬ä½¿ç¨VC/JBuilder,ä¼ä½¿ç¨ VC/JBuilderå¼åä¸ä¸ªHello Worldç¨åºï¼å°±å¿ä¸è¿çåä¸ç宣åï¼"æä¼è½¯ä»¶å¼åäº"ï¼ç®åä¸ä¹å¤§è¨ä¸æå°åä¸"ç²¾éVC/Java"ãç»æå°è½¯ä»¶å ¬å¸é¢è¯æ¶è¦ä¹è¢«ä¸ä¸¤ä¸æåèµ°äºï¼è¦ä¹è¢«é©³çä½æ å®è¤ï¼æ å°èªå®¹ãå°å¤ç¢°å£ä¹åæç¥éæ§èµ·ãC++ç¼ç¨ææ³ããJavaç¼ç¨ææ³ãä»ç»é»ç ï¼æ©ç¥å¦æ¤ä½å¿ å½ååã
"ä½ ç°å¨è®²ç©¶ç®åæ¹ä¾¿ï¼ä½ 以åç路就é¿äº"ï¼å¥½è±¡ä¹æ¯ä½ç»ä¸çåæã
1.4ãå¤å®è·µ,å¿«å®è·µ
å½ç«¯æ·çã为å¦ä¸é¦ç¤ºåä¾ãä¸æç©·åå°ä¸å¯åå°çæ äºã
ä»åï¼åå·è¾¹å¢æ两个åå°ï¼ä¸ä¸ªè´«ç©·ï¼ä¸ä¸ªæé±ãä¸å¤©ï¼ç©·åå°å¯¹å¯åå°è¯´ï¼"ææç®å»åæµ·æå£ï¼ä½ çæä¹æ ·ï¼"å¯åå°è¯´ï¼"è¿é离åæµ·æå åéè¿ï¼ä½ é ä»ä¹å»å¢ï¼"ç©·åå°è¯´ï¼"æåªè¦ä¸ä¸ªæ°´éµï¼ä¸ä¸ªé¥ç¢å°±å¤äºã"å¯åå°ä¸ºé¾å°è¯´ï¼"å å¹´åæå°±æç®ä¹°æ¡è¹å»åæµ·ï¼å¯è³ä»æ²¡å»æï¼ä½ è¿æ¯å«å»å§ï¼" ä¸å¹´ä»¥åï¼å¯åå°è¿å¨ä¸ºç§èµè¹åªç¹é±ï¼ç©·åå°å´å·²ç»ä»åæµ·æå£åæ¥äºã
è¿ä¸ªæ äºå¯è§£è¯»ä¸ºï¼ä»»ä½äºæ ï¼ä¸æ¦èè好äºï¼å°±è¦é©¬ä¸ä¸è·¯ï¼ä¸è¦çå°åå¤å¨å ¨ä¹åï¼åå»å¹²äºæ ãåå¦äºæ åå¤èèå¨å ¨äºåä¸è·¯çè¯ï¼å«äººæææ·è¶³å ç»äºã软件å¼åæ¯ä¸é¨å·¥ç¨å¦ç§ï¼æ³¨éçå°±æ¯å®è·µï¼"ååå¨å£ä¸å¨æ"对软件å¼å人åæ¥è®²æ ¹æ¬å°±æ¯é误çï¼ä»ä»¬æå¡"å¨æè³ä¸"ï¼ä½å«å®³æï¼ä»ä»¬å¤§å¤æ¸©æå°é ï¼æ²¡ææ´åå¾åï¼è½ç¶ææ¶åè¬å¤´å¢é¢çä¸å¯"æ¯å°çè¨"æ ·ãæåè¾é«äººè®¤ä¸ºï¼å¦ä¹ ç¼ç¨çç§è¯æ¯ï¼ç¼ç¨ãç¼ç¨ãåç¼ç¨ï¼ç¬è 深表èµåãä¸ä» è¦å¤å®è·µï¼èä¸è¦å¿«å®è·µãæ们å¨ç书çæ¶åï¼ä¸è¦çå°ä½ å®å ¨ç解äºæå¨ææ²ä»£ç ï¼èæ¯åºè¯¥å¨ç书çåæ¶æ²ä»£ç ï¼ç¨åºè¿è¡çåç§æ åµå¯ä»¥è®©ä½ æ´å¿«æ´ç¢åºçææ¡ç¥è¯ç¹ã
1.5ãå¤åèç¨åºä»£ç
ç¨åºä»£ç æ¯è½¯ä»¶å¼åæéè¦çææä¹ä¸ï¼å ¶ä¸æ¸éäºç¨åºåçææ³ä¸çµéã许å¤äººè¢«ãä»åå¥ä¾ ä¼ ãä¸åç¾çç±æ æ äºæå¨,æ²å§çç»å±æ´æä¸ç§ç¼ºæ¾ç¾ã为ä»ä¹è¦ä»¥æ²å§ç»å°¾ï¼æ®è¯´æ¯å 为åãä»åå¥ä¾ ä¼ ãçç¨åºå失æèå®æäºè¿æ ·çç»å±ï¼ä»æèªå·±çæè§èå ¥å°æ¸¸æä¸ï¼å´è®©ä¼å¤çä»åè¿·æ¼è å¹æ¯ã
å¤å¤åè代ç ä¾åï¼å¯¹Javaèè¨æåèæç®[4.3],æAPIç±»çæºä»£ç (JDKå®è£ ç®å½ä¸çsrc.zipæ件)ï¼ä¹å¯ä»¥ç 究ä¸äºå¼æºç软件ææ¡æ¶ã
1.6ãå 强è±æé 读è½å
对å¦ä¹ ç¼ç¨æ¥è¯´ï¼ä¸è¦æ±è±è¯, ä½ä¸è½ä¸ç¹ä¸ä¼,ãæèµ·ç åJava APIææ¡£(åèæç®[4.4])è¿äºä¸è¥¿è¿æ¯è¦è½çæç,è¿ç带æµé½å¯ä»¥ï¼æè¾¹åå¼å¯ä¸ä¸ª"éå±±è¯é¸"ãçå¤äºå°±ä¼è¶æ¥è¶çç»ãå¨å¦Javaçåæ¶å¦ä¹ è±æï¼ä¸ç®åéå¤å¥½ãå¦å¤å¥½å¤è½¯ä»¶éè¦å°è±æç½ç«ä¸è½½ï¼ä½ è¦è½å¤æ¾å°å®ä»¬ï¼è¿äºæ¯æåºæ¬çè¦æ±ãè±è¯å¥½å¯¹ä½ å¦ä¹ æå¾å¤§ç帮å©ãå£è¯å¥½çè¯æ´ææºä¼è¿å ¥ç®¡çå±ï¼è¿èå¯ä»¥æ为å¥åç¨åºåç"å¨æç®"ã
1.7ãä¸ä¸å¾å·²æ请æå«äºº
ç¬è å¨Martixä¸Java论åçå¨çº¿è¾ 导系ç»ä¸è§£å³å¦çé®é¢æ¶åç°ï¼å¤§é¨åçé®é¢å¦çç¨åæèå°±å¯ä»¥è§£å³ã请æå«äººä¹åï¼ä½ åºè¯¥å åçå¦ä¸å 个é®é¢ã
ä½ æ¯å¦å¨googleä¸æç´¢äºé®é¢ç解å³åæ³ï¼
ä½ æ¯å¦æ¥çäºJava APIææ¡£ï¼
ä½ æ¯å¦æ¥æ¾è¿ç¸å ³ä¹¦ç±ï¼
ä½ æ¯å¦å代ç æµè¯è¿ï¼
å¦æåçé½æ¯"æ¯"çè¯ï¼èä¸è¿æ²¡ææ¾å°è§£å³åæ³ï¼åé®å«äººä¸è¿ãè¦ç¥éç¬ç«æèçè½åå¯¹ä½ å¾éè¦ãè¦ç¥éç¨åºåçæ¶é´æ¯å¾å®è´µçã
1.8ãå¤è¯»å¥½ä¹¦
书ä¸èªæé¢å¦çãæ¯å°çè¨æ¯ä¸ä¸ªé¥±è¯»ç¾¤ä¹¦ç人ãè½ç¶æ²¡æ读å®å¤§å¦ï¼ä½ä¹å²çæ¶åæ¯å°çè¨å°±å·²ç»è¯»å®äºææçç¾ç§å ¨ä¹¦ï¼æ以ä»ç²¾é天æãåå²ãå°çççåç±»å¦ç§ï¼å¯ä»¥è¯´æ¯å°?è¨ä¸ä» æ¯å½ä»ä¸çä¸éé±çé¦å¯ï¼èä¸ä¹å¯ä»¥ç§°å¾ä¸æ¯ç¥è¯çå·¨å¯ã
ç¬è å¨ç»å¦çä¸è¯¾çæ¶åç»å¸¸ä¼ç»ä»ä»¬æ¨è书ç±ï¼å°åæ¥å¦çå®å¨å¿æ å¯å¿å¼å§æ±æ¨ï¼"天åï¼è¿ä¹å¤ä¹¦å°ä»ä¹æ¶åæè½çå®äº"ï¼"å¦è½¯ä»¶å¼åï¼æè§ä¸äºè´¼è¹ "ãè¿æ¶åï¼æçåçä¸è¬æ¯ï¼"å«çæ¥ï¼ä»ä¹æ¶åå¸¦ä½ ä»¬å»ççæç书æ¿ï¼å°ç°å¨æ¯æè±å¨ææ¯ä¹¦ç±ä¸çé±å ï¼è¿å¨è½¯ä»¶å¼å人åä¹ä¸è¿åªè½å¤ç®æ¯ä¸çç "ï¼å¦çå½åºæåãï¼æ³¨ï¼è¿ä¸é¨åå¦çæ¯åå¦è½¯ä»¶å¼åçï¼
1.9ã使ç¨åéçå·¥å ·
工欲åå ¶äºå¿ å å©å ¶å¨ã软件å¼åå å«åç§åæ ·çæ´»å¨ï¼éæ±æ¶éåæã建ç«ç¨ä¾æ¨¡åã建ç«åæ设计模åãç¼ç¨å®ç°ãè°è¯ç¨åºãèªå¨åæµè¯ãæç»éæççï¼æ²¡æå·¥å ·å¸®å¿å¯ä»¥è¯´æ¯å¯¸æ¥é¾è¡ãå·¥å ·å¯ä»¥æé«å¼åæçï¼ä½¿è½¯ä»¶çè´¨éæ´é«BUGæ´å°ãç»å称æçæ¦å¨ãå°é£è±æå¶çå¯ä¼¤äººçå¢çå°±å¾é«äºï¼æ æèææï¼æä¸æ åå¿ä¸æåè¿æ ·çå¢çå ä¹ä¸å¯ä¼åã
2ï¼è½¯ä»¶å¼åå¦ä¹ 路线
两åå¤å¹´çå家ææ³ååä¹éï¼ä¸åº¸çææ³éå ¥éª¨é«ï¼æ¢ä¸åè¿ä¹ä¸ä¿å®å¹¶éä¸åº¸ä¹éï¼èæ¯æ¾å¯»å¦ä¹ 软件å¼åçæ£ç¡®è·¯çº¿ä¸è§å¾ã
ä»è½¯ä»¶å¼å人åçç涯è§åæ¥è®²ï¼æ们å¯ä»¥å¤§è´å为ä¸ä¸ªé¶æ®µï¼è½¯ä»¶å·¥ç¨å¸â软件设计å¸âæ¶æ设计å¸æ项ç®ç®¡çå¸ãä¸æ³å½å å¸ çå£«å µä¸æ¯å¥½å£«å µï¼ä¸æ³å½æ¶æ设计å¸æ项ç®ç®¡çå¸çç¨åºåä¹ä¸æ¯å¥½çç¨åºåãæ们åºè¯¥åªåå¾ä¸èµ°ã让æ们å æ´çä¸ä¸å¼ååºç¨è½¯ä»¶éè¦å¦ä¹ ç主è¦ææ¯ã
Aï¼åºç¡ç论ç¥è¯ï¼å¦æä½ç³»ç»ãç¼è¯åçãæ°æ®ç»æä¸ç®æ³ã计ç®æºåççï¼å®ä»¬å¹¶éä¸éè¦ãå¦ä¸æ³æ为计ç®æºç§å¦å®¶çè¯ï¼å¯ä»¥éå"ç¨å°çæ¶ååæ¥å¦"çååã
Bï¼ä¸é¨ç¼ç¨è¯è¨ï¼ç°å¨åºæ¬ä¸é½æ¯é¢å对象çè¯è¨ï¼Java/C++/C#ççãå¦æåWEBå¼åçè¯è¿è¦å¦ä¹ HTML/JavaScriptççã
Cï¼ä¸ç§æ¹æ³å¦æè 说ææ³ï¼ç°å¨åºæ¬é½æ¯é¢å对象ææ³ï¼OOA/OOD/设计模å¼ï¼ãç±æ¤èè¡ççåºäºç»ä»¶å¼åCBD/é¢åæ¹é¢ç¼ç¨AOPççã
Dï¼ä¸ç§å ³ç³»åæ°æ®åºï¼ORACLE/SqlServer/DB2/MySQLçç
Eï¼ä¸ç§æé«ç产ççIDEéæå¼åç¯å¢JBuilder/Eclipse/VS.NETçã
Fï¼ä¸ç§UMLå»ºæ¨¡å·¥å ·ï¼ç¨ROSE/VISIO/é¢ç¬è¿è¡å»ºæ¨¡ã
Gï¼ä¸ç§è½¯ä»¶è¿ç¨ï¼RUP/XP/CMMççï¼éè¿è½¯ä»¶è¿ç¨æ¥ç»ç»è½¯ä»¶å¼åçä¼å¤æ´»å¨ï¼ä½¿å¼åæµç¨ä¸ä¸åè§èåãå½ç¶è¿æå ¶ä»çä¸äºè½¯ä»¶å·¥ç¨ç¥è¯ã
Hï¼é¡¹ç®ç®¡çãä½ç³»ç»æãæ¡æ¶ç¥è¯ã
æ£ç¡®ç路线åºè¯¥æ¯ï¼BâCâEâFâGâHã
è¿éè¦è¡¥å å ç¹ï¼
1ï¼ï¼å¯¹äºAä¸Cè¦è¡¥å çæ¯ï¼æ们åºè¯¥å¨å®è·µä¸éæ¥é¢æç¼ç¨ç论ä¸ç¼ç¨ææ³ãæ°ææ¯è½ç¶ä¸ææ¶ç°ï¼æ´æ°é度令人ç¼è±çä¹±é¾éçè±ï¼ä½ä¸åä¸ç¦»å ¶å®ï¼ç¼ç¨ç论ä¸ç¼ç¨ææ³çååå´å¾æ ¢ãææ¡äºç¼ç¨ç论ä¸ç¼ç¨ææ³ä½ å°±ä¼ææ¨äºè§æ¥ä¹æãé¢å对象çææ³å¨ç®åæ¥è®²æ¯ç¸å½å ³é®çï¼æ¯å¼ºå¿ææ¯ä¹ä¸ï¼å¨ä¸é¢éè¦å¤æå ¥æ¶é´ï¼ç»ä½ çåæ¥ä¹ä¼è®©ä½ æåã
2ï¼ï¼å¯¹äºæ°æ®åºæ¥è¯´æ¯ç¬ç«å¦ä¹ çï¼è¿ä¸ªæ¶æºå°±ç±ä½ æ¥å³å®å§ã
3ï¼ï¼ç¼ç¨è¯è¨ä½ä¸ºå¦ä¹ 软件å¼åç主线ï¼èå ¶ä½çä½ä¸ºè¾ 线ã
4ï¼ï¼è½¯ä»¶å·¥ç¨å¸çéäºBãCãEãDï¼è½¯ä»¶è®¾è®¡å¸çéäºBãCãEãDãFï¼æ¶æ设计å¸çéäºCãFãHã
3ï¼å¦ä½å¦ä¹ Java?
3.1 Javaå¦ä¹ 路线
3.1.1 åºç¡è¯æ³åJavaåç
åºç¡è¯æ³åJavaåçæ¯å°åºï¼å°åºä¸ç¢é ï¼ç¹å¦æ²å°ä¸å»ºæ©å¤©å¤§å¦ï¼æ¯ç¸å½å±é©çãå¦ä¹ Javaä¹æ¯å¦æ¤ï¼å¿ é¡»è¦ææå®çåºç¡ï¼ä½ æè½å¨J2EEã J2MEé¢å游åæä½ãåå SCJPï¼SUNå ¬å¸è®¤è¯çJavaç¨åºåï¼èè¯ä¸å¤±ä¸ºä¸ä¸ªå¥½æ¹æ³ï¼åå ä¹ä¸æ¯ä¸ºäºå¯¹å¾èµ·ä½ 交ç大æ´èè¯è´¹ï¼ä½ ä¼æ´åªåå¦ä¹ ï¼åå ä¹äºæ¯SCJPèè¯è½å¤è®©ä½ æåºç¡æå¾å¾ç¢é ï¼å®è¦æ±ä½ è·JDKä¸æ ·çæJavaåºç¡ç¥è¯ï¼ä½æ¯ä½ åä¸ä¸è¦è®¤ä¸ºèè¿äºSCJPå°±æå¤äºä¸èµ·ï¼å°±è½å¤è·å¾è½¯ä»¶å ¬å¸çéçï¼å°±è½å¤è·åé«èªï¼è¿æ ·çæ³æ³ä¹æ¯å¾å±é©çãè·å¾"çæ£"çSCJPåªè½è¯æä½ çåºç¡è¿è¿å¾å»ï¼ä½ç¦»å®é å¼åè¿æå¾é¿çä¸æ®µè·¯è¦èµ°ã
3.1.2 OOææ³çé¢æ
ææ¡äºåºç¡è¯æ³åJavaç¨åºè¿è¡åçåï¼æ们就å¯ä»¥ç¨Javaè¯è¨å®ç°é¢å对象çææ³äºãé¢å对象ï¼æ¯ä¸ç§æ¹æ³å¦;æ¯ç¬ç«äºè¯è¨ä¹å¤çç¼ç¨ææ³;æ¯ CBDåºäºç»ä»¶å¼åçåºç¡;å±äºå¼ºå¿ææ¯ä¹ä¸ãå½ä»¥åå å·¥ä½éè¦è½¬å°å«çé¢å对象è¯è¨çæ¶åï¼ä½ ä¼æå°ç¹å«ççæ亲åï¼å¦èµ·æ¥åååæ°´è¿ä¹ç®åã
使ç¨é¢å对象çææ³è¿è¡å¼åçåºæ¬è¿ç¨æ¯ï¼
âè°æ¥æ¶ééæ±ã
â建ç«ç¨ä¾æ¨¡åã
âä»ç¨ä¾æ¨¡åä¸è¯å«åæç±»åç±»ä¸ç±»ä¹é´çéæå¨æå ³ç³»ï¼ä»è建ç«åæ模åã
âç»ååæ模åå°è®¾è®¡æ¨¡åã
âç¨å ·ä½çææ¯å»å®ç°ã
âæµè¯ãé¨ç½²ãæ»ç»ã
3.1.3 åºæ¬APIçå¦ä¹
è¿è¡è½¯ä»¶å¼åçæ¶åï¼å¹¶ä¸æ¯ä»ä¹åè½é½éè¦æ们å»å®ç°ï¼ä¹å°±æ¯ç»å ¸åè¨æ说ç"ä¸éè¦éæ°åæè½®å"ãæ们å¯ä»¥å©ç¨ç°æçç±»ãç»ä»¶ãæ¡æ¶æ¥æ建æ们çåºç¨ï¼å¦SUNå ¬å¸ç¼å好äºä¼å¤ç±»å®ç°ä¸äºåºå±åè½ï¼ä»¥åæ们ä¸è½½è¿æ¥çJARæ件ä¸å å«çç±»,æ们å¯ä»¥è°ç¨ç±»ä¸çæ¹æ³æ¥å®ææäºåè½æ继æ¿å®ãé£ä¹è¿äºç±»ä¸ç©¶ç«æä¾äºåªäºæ¹æ³ç»æ们使ç¨ï¼æ¹æ³çåæ°ä¸ªæ°åç±»åæ¯ï¼ç±»çæé å¨éä¸éè¦åæ°ï¼æ»ä¸å¯è½SUNå ¬å¸çå·¥ç¨å¸æå½é é¿éçè³é£æ´è¿æµ·æ¥åè¯ä½ ä»ç¼åç类该å¦ä½ä½¿ç¨å§ãä»ä»¬åªè½æä¾ææ¡£ç»æ们æ¥çï¼Java DOCææ¡£ï¼åèæç®4.4ï¼å°±æ¯è¿æ ·çææ¡£ï¼å®å¯ä»¥è¯´æ¯ç¨åºåä¸ç¨åºå交æµçææ¡£ã
åºæ¬APIæçæ¯å®ç°äºä¸äºåºå±åè½çç±»ï¼éç¨æ§è¾å¼ºçAPIï¼å¦å符串å¤ç/è¾å ¥è¾åºççãæ们åæå®æ为类åºãçæAPIçæ¹æ³ä¸æ¯å¤æ¥Java DOCææ¡£ï¼åèæç®4.4ï¼ï¼äºæ¯ä½¿ç¨JBuilder/EclipseçIDEç代ç æ示åè½ã
3.1.4 ç¹å®APIçå¦ä¹
Javaä»å ¥çé¢åå¾å¹¿æ³ï¼ä¸åçé¢åæä¸åçAPIï¼æ²¡æ人çæææçAPIï¼å¯¹ä¸è¬äººèè¨åªæ¯çæå·¥ä½ä¸è¦ç¨å°çAPIãå¦æä½ åçé¢å¼åï¼é£ä¹ä½ éè¦å¦ä¹ Swing/AWT/SWTçAPIï¼å¦æä½ è¿è¡ç½ç»æ¸¸æå¼åï¼ä½ éè¦æ·±å ¥äºè§£ç½ç»API/å¤åªä½API/2D3Dçï¼å¦æä½ åWEBå¼åï¼å°±éè¦çæServletçAPIå¦ãæ»ä¹ï¼éè¦æ ¹æ®å·¥ä½çéè¦æä½ çå ´è¶£åå±æ¹åå»éæ©å¦ä¹ ç¹å®çAPIã
3.1.5 å¼åå·¥å ·çç¨æ³
å¨å¦ä¹ åºç¡è¯æ³ä¸åºæ¬çé¢å对象æ¦å¿µæ¶ï¼ä»é»ç¼è¯è¨çç»ç¨åº¦çè§åº¦èèï¼æ们æ¨è使ç¨çå·¥å ·æ¯Editplus/JCreator+JDK,è¿æ¶åä¸è¦æ¥äºä¸æJBuilder/Eclipseçéæå¼åç¯å¢ï¼ä»¥å è¿äºå ³æ³¨IDEç强大åè½èåæ£å¯¹Javaææ¯æ¬èº«ç注æåãè¿äºè¿ä¸é¶æ®µä½ å°±å¯ä»¥å¼å§çæ IDEäºã
ç¨åºåæ¥å¸¸å·¥ä½å æ¬å¾å¤æ´»å¨ï¼ç¼è¾ãç¼è¯åæ建ãè°è¯ãåå æµè¯ãçæ¬æ§å¶ãç»´æ模åä¸ä»£ç åæ¥ãææ¡£çæ´æ°ççï¼å ä¹æ¯ä¸é¡¹æ´»å¨é½æä¸é¨çå·¥å ·ï¼å¦æç¬ç«ä½¿ç¨è¿äºå·¥å ·çè¯ï¼ä½ å°ä¼å¾çè¦ï¼ä½ éè¦å¨å æ»¡å·¥å ·çä»»å¡æ ä¸ä¸æçåæ¢ï¼æçå¾ä½ä¸ï¼ä¹å¾å®¹æåºéãå¨JBuilderã EclipseçIDEä¸å·²ç»èªå¨éæç¼è¾å¨ãç¼è¯å¨ãè°è¯å¨ãåå æµè¯å·¥å ·JUnitãèªå¨æå»ºå·¥å ·ANTãçæ¬æ§å¶å·¥å ·CVSãDOCææ¡£çæä¸æ´æ°ççï¼çè³å¯ä»¥æUMLå»ºæ¨¡å·¥å ·ä¹éæè¿å»ï¼åæä¾äºä¸°å¯çå导帮å©çææ¡æ¶ä»£ç ï¼è®©æ们çå¼ååå¾æ´è½»æ¾ãåºè¯¥è¯´IDEåå±çè¶å¿å°±æ¯éæ软件å¼åä¸è¦ç¨å°çå ä¹ææå·¥å ·ã
ä»å¼åæççè§åº¦èèï¼ä½¿ç¨IDEæ¯å¿ ç»ä¹è·¯ï¼ä¹æ¯ä»ä¸ä¸ªå¦çå°ä¸ä¸ªèä¸ç¨åºå转åçéç¨ç¢ã
Javaå¼å使ç¨çIDE主è¦æEclipseãJBuilderãJDeveloperãNetBeansçå ç§ï¼èEclipseãJBuilder å æçå¸åºä»½é¢æ¯æ大çãJBuilderå¨è¿å å¹´æ¥ä¸ç´æ¯Javaéæå¼åç¯å¢ä¸çé¸ä¸»ï¼å®æ¯ç±å¤åç¨åºåå°æ¬çBorlandå ¬å¸å¼åï¼å¨ç¡ç弥漫ç Java IDE大æä¸,ä»¥å ¶å¿«éççæ¬æ´æ°å»è´¥IBMçVisual Age for Javaçèæå°±ä¸çªä¼ä¸ãIBMå¨Visual Age for Javaä¸å·²ç»æ å©å¯å¾ä¹ä¸ï¼å¹²èå°ä¹è´¡ç®ç»å¼æºç¤¾åºï¼æ为Eclipseçå身ï¼çæè°"æ³æè±æåä¸æ"ãæµ´ç«éççEclipseä»¥å ¶å¼æ¾å¼çæ件æ©å±æºå¶ãå è´¹å¼æºè·å¾å¹¿å¤§ç¨åºåï¼å æ¬å ä¹ææç骨ç°çº§ç¨åºåï¼çéçï¼æå ·åå±æ½åã
3.1.6 å¦ä¹ 软件工ç¨
对å°å项ç®èè¨ï¼ä½ å¯è½è®¤ä¸ºè½¯ä»¶å·¥ç¨æ²¡å¤ªå¤§çå¿ è¦ãéç项ç®çå¤ææ§è¶æ¥è¶é«ï¼è½¯ä»¶å·¥ç¨çå¿ è¦æ§æä¼ä½ç°åºæ¥ãåè§"软件å¼åå¦ä¹ 路线"å°èã
3.2å¦ä¹ è¦ç¹
ç¡®ç«çå¦ä¹ 路线ä¹åï¼æ们è¿éè¦æ»ç»ä¸ä¸Javaçå¦ä¹ è¦ç¹ï¼è¿äºè¦ç¹å¨åæå¤å¤å°å°æå°è¿ï¼åªæ¯ç¬è è§å¾è¿äºå°æ¹ç¹å«è¦æ³¨ææ对å®ä»¬è¿è¡æ±æ»ï¼ä¸è¦å«æå©å©å¦å¦åã
3.2.1å¤æ¥APIææ¡£
å½ç¨åºåç¼å好æäºç±»ï¼è§å¾å¾ææå°±æ,æ³æå®è´¡ç®ç»åä½è¦é¾çåè¡ãè¿æ¶åä½ è¦ä½¿ç¨"Javadoc"å·¥å ·ï¼å å«å¨JDKä¸ï¼çææ åçJava DOCææ¡£,ä¾åè¡ä½¿ç¨ãJ2SE/J2EE/J2MEçDOCææ¡£æ¯ç¨åºåä¸ç¨åºå交æµçå·¥å ·ï¼å ä¹äººæä¸ä»½ï¼é¤äºèé¸ä¹å¤ãJ2SE DOCææ¡£å®æ¹ä¸è½½å°åï¼/j2se/1.5.0/download.jspï¼ä½ å¯ä»¥å°googleæç´¢CHMçæ¬ä¸è½½ãä¹å¯ä»¥å¨çº¿æ¥çï¼/j2se/1.5.0/docs/api/index.htmlã
å¯¹å¾ DOCææ¡£è¦åæ¯è¯å½ï¼æ©ä¸èµ·åºå¿µä¸éï¼åé¥ç¡è§å念ä¸éã
å½éè¦æ项åè½çæ¶åï¼ä½ åºè¯¥å æ¥ç¸åºçDOCææ¡£ççæ没æç°æçå®ç°ï¼æçè¯å°±ä¸å¿ å³ç¥è´¹å¿äºç´æ¥ç¨å°±å¯ä»¥äºï¼æ¾ä¸å°çæ¶åæèèèªå·±å®ç°ã使ç¨æ¥éª¤ä¸è¬å¦ä¸ï¼
âæ¾ç¹å®çå ï¼å ä¸è¬æ ¹æ®åè½ç»ç»ã
âæ¾éè¦ä½¿ç¨ç±»ï¼ç±»å½åè§èçè¯æ们ç±ç±»çååå¯çåºä¸äºã
âéæ©æé å¨ï¼å¤§å¤æ°ä½¿ç¨ç±»çæ¹å¼æ¯å建对象ã
âéæ©ä½ éè¦çæ¹æ³ã
3.2.2 æ¥ä¹¦/google->å代ç æµè¯->æ¥çæºä»£ç ->请æå«äºº
å½æ们éå°é®é¢çæ¶å该å¦ä½è§£å³ï¼
è¿æ¶åä¸è¦æ¥çé®å«äººï¼å¤ªç®åçé®é¢ï¼æ²¡ç»è¿æèçé®é¢ï¼å«äººä¼å æ¤èç§ä¸èµ·ä½ ãå¯ä»¥å æ¾æ¾ä¹¦ï¼å°googleä¸æä¸ä¸ççï¼ç»å¤§é¨åé®é¢åºæ¬å°±è§£å³äºãèå"æäºç±»/æ¹æ³å¦ä½ä½¿ç¨çé®é¢"ï¼DOCæ档就æ¯çæ¡ã对æäºç¥è¯ç¹æçææ¯ï¼å代ç æµè¯ä¸ä¸ï¼ä¼ç»ä½ çä¸æ·±å»çå°è±¡ãèæçé®é¢ï¼ä½ å¯è½éè¦ç´æ¥ç APIçæºä»£ç éªè¯ä½ çæ³æ³ãä¸ä¸å¾å·²æå»è¯·æå«äººã
3.2.3å¦ä¹ å¼æºè½¯ä»¶ç设计ææ³
Javaé¢åæ许å¤æºä»£ç å¼æ¾çå·¥å ·ãç»ä»¶ãæ¡æ¶ï¼JUnitãANTãTomcatãStrutsãSpringãJive论åãPetStoreå® ç©åºççå¤å¦çæ¯ãè¿äºå¯æ¯åè¾ç»æ们çä¸çç°å®åãå ¥å®å±±è空æå½ï¼ä½ å¿çåï¼å¯¹è¿äºå·¥å ·ãæ¡æ¶è¿è¡åæï¼é¢ä¼å ¶ä¸ç设计ææ³ï¼ææä¸æ¥è¯´ä¸å®ä½ ä¹è½åä¸ä¸ªXXXæ¡æ¶ä»ä¹çï¼é£å ä¸æãåæå¼æºè½¯ä»¶å ¶å®æ¯ä½ æé«ææ¯ãæé«å®æè½åç便æ·æ¹æ³ã
3.2.4 è§èçéè¦æ§
没æè§ç©ï¼ä¸ææ¹åãè¿éçè§èæ两å±å«ä¹ã第ä¸å±å«ä¹æ¯ææ¯è§èï¼å¤å°/docs/codeconv/ï¼ä¸æçä¹æï¼åï¼è¿è¦é®æå¨åªï¼è¯·åè3.2.2èã
3.2.5 ä¸å±éäºJava
å¾ä¸å¹¸ï¼å¾å¹¸è¿ï¼è¦å¦ä¹ çä¸è¥¿è¿æå¾å¤ãä¸å¹¸çæ¯å 为è¦å¦çä¸è¥¿å¤ªå¤ä¸å¤åï¼æ²¡æ¶é´éªèå©å®¶äººæ女æåï¼å¯¼è´èº«å¿ç²æ«ï¼ä¸¥éè çè³å¯¼è´æéçã幸è¿çæ¯å«äººè¦æ¢ä½ é¥ç¢ç»éæäºï¼ä»ä»¬æ她们éè¦ä»åºå¾å¤æè½è¾¾æå¿æ¿ã
Javaä¸è¦å¤ç«å°å»å¦ä¹ ï¼éè¦ç»¼åå¦ä¹ æ°æ®ç»æãOOPã软件工ç¨ãUMLãç½ç»ç¼ç¨ãæ°æ®åºææ¯çç¥è¯ï¼ç¨æ¨ªå纵åçæ¯è¾èæ³çæ¹å¼å»å¦ä¹ ä¼æ´ææãå¦å¦ä¹ Javaéåçæ¶åæ¾æ°æ®ç»æç书ççï¼å¦JDBCçæ¶åå¤ä¹ æ°æ®åºææ¯ï¼éåçä¾ç¶æ¯"éè¦çæ¶ååå¦"çååã
4ï¼ç»æè¯
éè¦å¼ºè°çæ¯ï¼å¦ä¹ 软件å¼åç¡®å®æä¸å®çé¾åº¦ï¼ä¹å¾è¾è¦ï¼éè¦ä»åºå¾å¤åªåï¼ä½åä¸ä¸è¦åéèåºãæ¬æå¦æè½å¯¹ä¸ç´å¾å¾å¨Javaç¥æ®¿ä¹å¤çæåææ帮å©çè¯ï¼ç¬è ä¹æ¬£æ °äºãååï¼æä¹å¬èµ·æ¥èæ°æ¨ªç§åï¼æ²¡åæ³ï¼å¨çµèçé¿æè¾å°ä¹ä¸ï¼é½å¿«åæå°è头äºãæåå¥ååä½ç¨åºåå°¤å ¶æ¯MMç¨åºåï¼å®æå·¥ä½å赶快è¿ç¦»çµèï¼æ®ãè¡æä¹±æ¥ãæ¥éï¼çµèè¾å°ä¼å¨ç½ççç®è¤ä¸é¢ç¹ç¼ä¸äºå°é»ç¹ï¼çèµ·æ¥é²è³æ æ¯â¦â¦ æèµ·æ天ç梦æ³è¿å¾é èªå·±ï¼
MFC中的InitInstance()函数应该怎样理解
不是,是源码源码游戏实例的初始化函数;比如分配内存空间啊什么的;
MFC的WinMain
使用MFC编程的程序员刚开始都会提出这样一个问题:我的程序是从哪儿开始执行的?回答是:从WinMain()开始执行的。提出这样的分享问题是由于在他们所编写的MFC应用中看不到WinMain()函数。这个函数是扒皮扒皮隐藏在MFC框架中,MFC的源码源码游戏设计者将它作得很通用(这主要得益于Window的消息驱动的编程机制,使得作一个通用的分享荣耀8内核源码WinMain()很容易),因此在一般情况下,扒皮扒皮无需更改WinMain()的源码源码游戏代码,MFC的分享设计者也不提倡程序员修改WinMain()的代码。在MFC中,扒皮扒皮实际实现WinMain()的代码是AfxWinMain()函数(根据其前缀Afx就知道这是一个全局的MFC函数)。
一个Win应用程序(或进程)是源码源码游戏由一个或多个并发的线程组成的,其中第一个启动的分享线程称为主线程,在Window下,扒皮扒皮一般将线程分成两大类,源码源码游戏界面线程和工作线程,分享工作线程就是一般的线程,它没有窗口,没有消息队列等,pybind11源码界面线程拥有一个或多个窗口,拥有一个消息队列和其他专属于界面线程的元素。在讨论AfxWinMain()之前,首先要简略提一下MFC中的两个重要的类,CWinThread和CWinApp,CWinThread是用来封装界面线程的类,CWinApp是从CWinThread派生而来的。在CWinThread中,有两个很重要的虚拟函数InitInstance()和ExitInistance(),MFC的程序员应该对这两个函数应该很熟悉。在CWinApp中,增加了另外一个虚拟函数InitApplication(),讨论AfxWinMain()的主要目的是看这些函数是如何被调用的。
AfxWinMain()的代码如下:
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL); file://在win下,hPrevInstance始终为NULL
int nReturnCode = -1;
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
// AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
goto InitFailure;
// App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;
// Perform specific initializations
if (!pThread->InitInstance())
{
if (pThread->m_pMainWnd != NULL)
{
TRACE0("Warning: Destroying non-NULL m_pMainWnd\n");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
nReturnCode = pThread->Run();
InitFailure:
AfxWinTerm();
return nReturnCode;
}
在上面的代码中,AfxGetThread()返回的是当前界面线程对象的指针,AfxGetApp()返回的idea无法debug源码是应用程序对象的指针,如果该应用程序(或进程)只有一个界面线程在运行,那么这两者返回的都是一个全局的应用程序对象指针,这个全局的应用程序对象就是MFC应用框架所默认的theApp对象(每次使用AppWizard生成一个SDI或MDI应用程序时,AppWizard都会添加CYourApp theApp这条语句,AfxGetApp()返回的就是这个theApp的地址)。
CWinApp::InitApplication(), CWinThread::InitInstance(), CWinThread::ExitInstance()是如何被调用的,从上面的代码一看就知,我不再赘述。下面我们把焦点放在CWinThread::Run()上。
MFC的控制中心――CWinThread::Run()
说CWinThread::Run()是MFC的控制中心,一点也没有夸大。在MFC中,所有来自于消息队列的消息的分派都是在CWinThread::Run()函数中完成的,同AfxWinMain()一样,这个函数也是对程序员是不可见的,其道理同AfxWinMain()的一样。
首先要提的联动自动发卡源码一点是,对每条从消息队列取出来的消息,MFC根据消息的类型,按照某个特定的模式进行分发处理,这个分发模式是MFC自己定义的。固定的消息分发流程和在这个流程中的可动态改变其行为的虚拟函数就构成了MFC的消息分发模式。应用程序可以通过重载这些虚拟函数,来局部定制自己的的消息分发模式。正是通过这些虚拟函数,MFC为应用程序提供了足够的灵活性。下面讨论的所有代码都来自于MFC源代码中的threadcore.cpp文件,它们都是CWinThread的成员。
CWinThread::Run()的结构
CWinThread::Run()的代码如下:
int CWinThread::Run()
{
ASSERT_VALID(this);
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
// acquire and dispatch messages until a WM_QUIT message is received.
for (;;)
{
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++))
bIdle = FALSE; // assume "no idle" state
}
// phase2: pump messages while available
do{
// pump message, but quit on WM_QUIT
if (!PumpMessage()) return ExitInstance();
// reset "no idle" state after pumping "normal" message
if (IsIdleMessage(&m_msgCur))
{
bIdle = TRUE;
lIdleCount = 0;
}
} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
}
ASSERT(FALSE); // not reachable
}
CWinThread::Run()的处理过程如下:
先根据空闲标志以及消息队列是否为空这两个条件判断当前线程是否处于空闲状态(这个“空闲”的含义同操作系统的含义不同,是MFC自己所谓的“空闲”),如果是,就调用CWinThread::OnIdle(),这也是我们比较熟悉的一个虚拟函数。
如果不是用源码快速建站,从消息队列中取出消息,进行处理,直到消息队列为空。
在这里,我们发现,MFC不是调用GetMessage()从线程消息队列中取消息,而是调用PeekMessage()。其原因在于,GetMessage()是一个具有同步行为的函数,如果消息队列中没有消息,GetMessage()会一直阻塞,使得线程处于睡眠状态,直到消息队列中有一条或多条消息,操作系统才会唤醒该线程,GetMessage()才会返回,如果线程处于睡眠状态了,就不会使线程具有MFC所谓的“空闲”状态了;而PeekMessage()则是一个具有异步行为的函数,如果消息队列中没有消息,它马上返回0,不会导致线程处于睡眠状态。
在上面的代码中,有两个函数值得探讨,一个是空闲处理函数OnIdle(),另外一个是消息分发处理函数PumpMessage()。不要忽视CWinThread的OnIdle()函数,它作了很多有意义的事情。下面讨论PumpMessage(),OnIdle()将在后面的章节里讨论。
CWinThread::Run()的核心――CWinThread::PumpMessage()
标题强调了PumpMessage()的重要性,Run()是MFC的控制中心,而PumpMessage()又是Run()的核心,所以从MFC的真正控制中心是PumpMessage()。PumpMessage()的代码极其简单:
BOOL CWinThread::PumpMessage()
{
ASSERT_VALID(this);
if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
return FALSE;
// process this message
if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
{
::TranslateMessage(&m_msgCur);
::DispatchMessage(&m_msgCur);
}
return TRUE;
}
首先,PumpMessage()调用GetMessage()从消息队列中取一条消息,由于PumpMessage()是在消息队列中有消息的时候才被调用的,所以GetMessage()会马上返回,根据其返回值,判断当前取出的消息是不是WM_QUIT消息(这个消息一般对是通过调用PostQuitMessage()放入线程消息队列的),如果是,就返回FALSE,CWinThread::Run()该退出了,CWinThread::Run()直接调用CWinThread::ExitInstance()退出应用程序。在GetMessage()的后面是我们所熟悉的TranslateMessage()和DispatchMessage()函数。
可以看出,是否调用TranslateMessage()和DispatchMessage()是由一个名称为PreTranslateMessage()函数的返回值决定的,如果该函数返回TRUE,则不会把该消息分发给窗口函数处理。
就我个人观点而言,正是有了这个PreTranslateMessage(),才使得MFC能够灵活的控制消息的分发模式,可以说,PreTranslateMessage()就是MFC的消息分发模式。
<三>MFC的特色――PreTranslateMessage()
经过层层扒皮,终于找到了CWinThread::Run()最具特色的地方,这就是PreTranslateMessage()函数。同前面使用SDK编写的显示”Hello, world!”程序的消息循环不同的地方在于,MFC多了这个PreTranslateMessage(),PreTranslateMessage()最先获得了应用程序的消息处理权!下面我们对PreTranslateMessage()进行剥皮式分析。同前面一样,首先看看实际的PreTranslateMessage()的代码:
BOOL CWinThread::PreTranslateMessage(MSG* pMsg)
{
ASSERT_VALID(this);
// if this is a thread-message, short-circuit this function
if (pMsg->hwnd == NULL && DispatchThreadMessageEx(pMsg)) return TRUE;
// walk from target to main window
CWnd* pMainWnd = AfxGetMainWnd();
if (CWnd::WalkPreTranslateTree(pMainWnd->GetSafeHwnd(), pMsg)) return TRUE;
// in case of modeless dialogs, last chance route through main
// window's accelerator table
if (pMainWnd != NULL)
{
CWnd* pWnd = CWnd::FromHandle(pMsg->hwnd);
if (pWnd->GetTopLevelParent() != pMainWnd)
return pMainWnd->PreTranslateMessage(pMsg);
}
return FALSE; // no special processing
}
PreTranslateMessage()的处理过程如下:
首先判断该消息是否是一个线程消息(消息的窗口句柄为空的消息),如果是,交给DispatchThreadMessageEx()处理。我们暂时不管DispatchThreadMessageEx(),它不是我们讨论的重点。
调用CWnd::WalkPreTranslateTree()对该消息进行处理,注意该函数的一个参数是线程主窗口的句柄,这是PreTranslateMessage()的核心代码,在后面会对这个函数进行详细的分析。
对于非模式对话框,这特别的、额外的处理。
下面详细讨论一下CWnd::WalkPreTranslateTree()函数,它的代码很简单:
BOOL PASCAL CWnd::WalkPreTranslateTree(HWND hWndStop, MSG* pMsg)
{
ASSERT(hWndStop == NULL || ::IsWindow(hWndStop));
ASSERT(pMsg != NULL);
// walk from the target window up to the hWndStop window checking
// if any window wants to translate this message
for (HWND hWnd = pMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
{
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
if (pWnd != NULL)
{
// target window is a C++ window
if (pWnd->PreTranslateMessage(pMsg))
return TRUE; // trapped by target window (eg: accelerators)
}
// got to hWndStop window without interest
if (hWnd == hWndStop)
break;
}
return FALSE; // no special processing
}
CWnd::WalkPreTranslateTree()的所使用的策略很简单,拥有该消息的窗口最先获得该消息的处理权,如果它不想对该消息进行处理(该窗口对象的PreTranslateMessage()函数返回FALSE),就将处理权交给它的父亲窗口,如此向树的根部遍历,直到遇到hWndStop(在CWinThread::PreTranslateMessage()中,hWndStop表示的是线程主窗口的句柄)。记住这个消息处理权的传递方向,是由树的某个一般节点或叶子节点向树的根部传递!
小结:
下面对这一章作一个小结。
MFC消息控制流最具特色的地方是CWnd类的虚拟函数PreTranslateMessage(),通过重载这个函数,我们可以改变MFC的消息控制流程,甚至可以作一个全新的控制流出来,在下面的一章会对MFC的实现作详细介绍。
只有穿过消息队列的消息才受PreTranslateMessage()影响,采用SendMessage()或其他类似的方式向窗口直接发送的而不经过消息队列的消息根本不会理睬PreTranslateMessage()的存在
传给PreTranslateMessage()的消息是未经翻译过的消息,它没有经过TranslateMessage()处理,在某些情况下,要仔细处理,以免漏掉消息。