版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
----------------------------精品word文檔值得下載值得擁有--------------------------------------------------------------------------精品word文檔值得下載值得擁有---------------------------------------------------------------------------------------------------------------------------------------------------------------------------從VC6到VC9移植代碼問題總結(jié)當(dāng)年在學(xué)校學(xué)習(xí)C編程的時候用的是TC2.0,后來學(xué)C++用TC3.0,有一天突然發(fā)現(xiàn)BorlandC++3.1的IDE比較好用,于是改用BC31,然后是BC4,但是到了BC5(還有BC5.02)的時候就玩不下去了,因為我那臺只有16M內(nèi)存的P100實在是跑不動這個龐然大物,在OWL和MFC之間“痛苦地”抉擇了一部電影的時間后,我決定放棄添加內(nèi)存的計劃,改用VisualC++試試。因為當(dāng)時內(nèi)存太貴了,不過電影很好看,我還記得名字是《西域雄獅》,講的是黃飛鴻到北美開寶之林分號的故事,還收了一個洋徒。。。你看這思維跳躍的,打住,說正事兒吧??赐觌娪昂笱b了一個VisualC++4.2,這Microsoft的東西就是爭氣,在我的破機(jī)器上跑得馬溜的快,于是就用買內(nèi)存的預(yù)算買了一本《VisualC++4.0從入門到精通》,那個時候的出版社就是效率低,這本書已經(jīng)是所有關(guān)于VC的書中最新的了,好像還看到一本《VisualC++1.5-2.x使用指南》,什么年代的事情了,還擺在書架上。哪像現(xiàn)在的出版社,簡直就是“與時俱進(jìn)”的典范,Microsoft那邊《Windows7》剛發(fā)布了個預(yù)覽版,這邊《下一代xxx揭密》就已經(jīng)上架了,唉,又扯遠(yuǎn)了,打住。沒多久VC5就出來了,好在這兩個版本的用戶界面變化不大(MFC的版本穩(wěn)定在4.2),我就在《VisualC++4.0從入門到精通》這本書的指導(dǎo)下“精通”了VC5。1998年的時候VisualC++6.0推出了,但是我一直堅持用VC5,1999年我畢業(yè)設(shè)計還是選擇用VC5,不為別的,就是因為當(dāng)時盜版的VC6都沒有幫助文件,就是缺少M(fèi)SDN,沒有這個還怎么寫代碼?畢業(yè)設(shè)計完成之后我從朋友那里弄到了傳說中的兩張MSDN光盤,于是開始用VC6,從此以后,VC6就一直存在于所有我用過的電腦中,后來VC7(7.1),VC8出來以后,VC6的地位也一直沒有動搖過,用C++開發(fā)軟件我首選VC6,我還為VC6開發(fā)了一個文件標(biāo)簽欄插件Tabbar,可以通過標(biāo)簽欄在打開的代碼文件之間快速切換,除此之外還具有很多其它功能,比如自動打包壓縮項目代碼。。。唉,又跑題了,打住。做人要與時俱進(jìn),這不,今年VC9也隨著VisualStudio2008發(fā)布了,再不趕上就真的老套了。說是這么說,不過心里還是有些余悸的,2006年的時候我曾經(jīng)試圖將我的一個工具軟件的代碼升級到VC8,但是我低估了新的編譯器的兼容性(當(dāng)年從VC5到VC6可是沒有那么多麻煩),上來就是一大堆編譯錯誤,警告就更是牛毛,當(dāng)時因為急著為工具軟件開發(fā)一個新功能,沒有時間解決這些問題,只好放下了,這一放就是兩年。我這個人喜歡自己做工具軟件,目的是為了方便自己,以前用VC6,覺得在代碼源文件之間切換很麻煩,但是WndTab太占用資源,于是就借鑒WndTab的部分代碼自己做了個標(biāo)簽欄插件Tabbar,還把從CodeProject上看到的好的創(chuàng)意都添加進(jìn)去,后來用SourceInsight,覺得它沒有文件標(biāo)簽欄太土,就給它做了個標(biāo)簽欄外掛(TabSiPlus),就這樣幾年下來竟然有幾百兆的工具代碼,這個移植的工作量可是非同小可,想著都怕怕呀!不過也沒辦法,這兩年主要用GCC做嵌入式開發(fā)了,沒有時間維護(hù)這些工具,自己在使用過程中累計下來的BUG和新需求也有一大堆,需要進(jìn)行升級了,適逢這次機(jī)會將其移植到VC9到也是個不錯的選擇。其實程序員自己給自己寫工具很有好處,比如我喜歡邊寫代碼邊聽音樂,于是我就把自己寫的MP3播放器集成到VC開發(fā)環(huán)境中,這樣就可以象操作VC的其它功能一樣選擇音樂文件,還比如。。。又扯遠(yuǎn)了,回到正題,講講移植過程中遇到的問題。首先可以直接用VisualStudio2008的打開VC6的工作區(qū)文件和項目文件(dsw和dsp),并將其升級為VS2008的解決方案格式和項目格式(sln和vcproj),VC9的編譯器相對于VC6有了很大的變化,一些編譯參數(shù)和鏈接參數(shù)被廢棄(比如/map:line),有一些改變了名稱,還有新增的選項,不過不用擔(dān)心,升級過程會自動對其進(jìn)行轉(zhuǎn)換,最終都會得到一個正確的解決方案和VC項目文件,這個過程不會遇到太多的麻煩,問題都出在隨后的編譯過程中,下面就將我在移植的過程中遇到的問題和我的解決方法總結(jié)一下,希望對還在用VC6維護(hù)代碼的朋友有所幫助。一、_WIN32_WINNT與_WIN32_IE設(shè)置沖突_WIN32_WINNT與_WIN32_IE設(shè)置不兼容會導(dǎo)致如下C1189致命錯誤:StdAfx.cppc:/programfiles/microsoftsdks/windows/v6.0a/include/sdkddkver.h(217):fatalerrorC1189:#error:_WIN32_WINNTsettingsconflictswith_WIN32_IEsettingStdAfx.cpp通常是項目中第一個編譯的文件,這個錯誤將導(dǎo)致編譯無法繼續(xù)進(jìn)行。產(chǎn)生這個錯誤的原因是原因是_WIN32_WINNT的版本定義太老,老的VC代碼對_WIN32_WINNT的典型設(shè)置是:#ifndef_WIN32_WINNT#define_WIN32_WINNT0x0400#endif0x0400相對于VS2008所帶的PlarformSDK(在文件sdkddkver.h中)中_WIN32_IE的定義來說太老了,導(dǎo)致不兼容,可以將其改成0x0501或更高的版本避免這個問題,如下所示:#ifndef_WIN32_WINNT#define_WIN32_WINNT0x0501#endif也可以將這三行_WIN32_WINNT定義刪除,這樣就會使用PlarformSDK中的_WIN32_WINNT定義,自然就不存在不兼容問題了。不過出于對老版本VC的兼容考慮(畢竟以后可能還要使用VC6編譯代碼),最好這樣修改:#if_MSC_VER<=1200//MFC6.0orearlier#ifndef_WIN32_WINNT#define_WIN32_WINNT0x0400#endif#endif二、afximpl.h文件中的語法錯誤MFC出現(xiàn)的時候STL還沒有成為C++的標(biāo)準(zhǔn),所以MFC使用一套自己的模版庫,比如CArray、CList、CMap等等,這些類型聲明都在afximpl.h文件中。原來在VC6編譯器適用的模版語法可能不適用VC9,特別是當(dāng)以下四個環(huán)境變量設(shè)置不兼容時,就會出現(xiàn)這個編譯錯誤,大致情況如下:e:/software/microsoftvisualstudio9.0/vc/atlmfc/src/mfc/afximpl.h(625):errorC2059:syntaxerror:'<L_TYPE_raw>'e:/software/microsoftvisualstudio9.0/vc/atlmfc/src/mfc/afximpl.h(625):errorC2238:unexpectedtoken(s)preceding';'e:/software/microsoftvisualstudio9.0/vc/atlmfc/src/mfc/afximpl.h(629):errorC2059:syntaxerror:'<L_TYPE_raw>'e:/software/microsoftvisualstudio9.0/vc/atlmfc/src/mfc/afximpl.h(629):errorC2238:unexpectedtoken(s)preceding';'合理調(diào)整stdafx.h中WINVER、_WIN32_WINNT、_WIN32_WINDOWS和_WIN32_IE的設(shè)置可以避免這個問題,將三個與Windows版本有關(guān)的環(huán)境變量設(shè)置為0x0501或更高版本,將IE版本的環(huán)境變量設(shè)置為0x0500以后的版本就可以解決這個問題。當(dāng)然,考慮到與舊的VC6代碼兼容,可以采用上一個問題中提到的最后一個解決辦法,用_MSC_VER進(jìn)行隔離。三、舊的CRT庫和新的安全CRT庫引起的C4996告警解決了環(huán)境變量設(shè)置不匹配導(dǎo)致的問題后,編譯過程就真正開始了,不過首先映入眼簾的應(yīng)該是成堆的C4996編譯告警,對每個使用了含字符串參數(shù)的CRT庫函數(shù)都會有C4996編譯告警,一個典型的輸出如下所示:f:/project/...../commonfunc.cpp(280):warningC4996:'strcpy':Thisfunctionorvariablemaybeunsafe.Considerusingstrcpy_sinstead.Todisabledeprecation,use_CRT_SECURE_NO_WARNINGS.Seeonlinehelpfordetails.e:/software/microsoftvisualstudio9.0/vc/include/string.h(74):seedeclarationof'strcpy'MSDNonline是這樣解釋的:為了顯著增加CRT庫的安全性,許多CRT函數(shù)都有了一個更安全的新版本,新版本和舊版本的區(qū)別就是新版本函數(shù)名多了一個_s后綴。只要一個CRT函數(shù)有新的安全版本,編譯器就會產(chǎn)生一個C4996告警,不過,出現(xiàn)這個告警的目的并不是說舊版本的CRT函數(shù)將淡出CRT庫,告警出現(xiàn)只是為了提醒程序員這個函數(shù)有更安全的版本存在。一種安全的或者是被鼓勵的做法是用安全版本的函數(shù)替換現(xiàn)有的CRT函數(shù),不過對于一個有相當(dāng)代碼量的項目,替換工作量也是巨大的,這可不是用名稱查找、替換就能簡單解決的問題,因為許多安全版本的CRT函數(shù)參數(shù)個數(shù)也發(fā)生了變化。也可以用預(yù)處理指令消除這個告警:#pragmawarning(disable:4996)或者定義_CRT_SECURE_NO_WARNINGS壓制這個告警(在stdafx.h中define或在項目屬性中設(shè)置預(yù)處理符號,PreProcessorDefinitions)。除了C語言的CRT函數(shù)外,POSIX兼容函數(shù)也存在這個告警,解決方法是用POSIX標(biāo)準(zhǔn)名稱替換(比如access換成_access)或者是定義_CRT_NONSTDC_NO_WARNINGS壓制這個告警(方法同上)。四、“CWinApp::Enable3dControls”引起的C4996告警這個是編譯使用了老的向?qū)傻腗FC代碼時遇到的問題,一個典型的告警信息輸出如下所示:CrpFileCrack.cppf:/project/...../crpfilecrack.cpp(52):warningC4996:'CWinApp::Enable3dControls':CWinApp::Enable3dControlsisnolongerneeded.Youshouldremovethiscall.e:/software/microsoftvisualstudio9.0/vc/atlmfc/include/afxwin.h(4818):seedeclarationof'CWinApp::Enable3dControls'通常向?qū)傻拇a是:#ifdef_AFXDLLEnable3dControls();//CallthiswhenusingMFCinasharedDLL#elseEnable3dControlsStatic();//CallthiswhenlinkingtoMFCstatically#endif這兩個函數(shù)的調(diào)用是舊的MFC版本對新版本的操作系統(tǒng)特性的支持,在新的(那個時候是新的)Windows95平臺上要這樣調(diào)用一下才能使用新的Windows3D樣式的控件,否則就是老的Win3.2樣子的控件。想當(dāng)初喜歡OWL就是因為感覺它的控件比較“酷”,比如那個帶底紋的對話框,菱形的checkbox,還有帶圖標(biāo)的“OK”按鈕,看到MFC作出來的灰灰的界面就覺得土,不過后來就知道MFC做界面也是很漂亮的,比如我做的。。。。,再打住。對于新的MFC版本來說已經(jīng)不需要再調(diào)用這兩個函數(shù)了,參考前面的方法,用_MSC_VER對其隔離就行了:#if_MSC_VER<=1200//MFC6.0orearlier#ifdef_AFXDLLEnable3dControls();//CallthiswhenusingMFCinasharedDLL#elseEnable3dControlsStatic();//CallthiswhenlinkingtoMFCstatically#endif#endif五、.def文件引起的連接告警對于普通的DLL項目中使用的.def文件通常會引起LNK4017鏈接告警,如下所示:./ComFunc.def(4):warningLNK4017:DESCRIPTIONstatementnotsupportedforthetargetplatform;ignoredCreatinglibrary./../Debug/ComFunc.libandobject./../Debug/ComFunc.exp一個典型的.def文件通常有以下內(nèi)容:LIBRARY"XorCryptor"DESCRIPTION'XorCryptorWindowsDynamicLinkLibrary'EXPORTS;Explicitexportscangohere..................消除這個連接告警的方法就是從.def文件中刪除DESCRIPTION描述信息,不過這個告警也不是什么大問題,不刪也可以。另一個可能產(chǎn)生的連接告警是LNK4222,通常出現(xiàn)在ocx控件和com組件的項目中,一個典型輸出是:Linking..../PlusInModule.def:warningLNK4222:exportedsymbol'DllCanUnloadNow'shouldnotbeassignedanordinal./PlusInModule.def:warningLNK4222:exportedsymbol'DllGetClassObject'shouldnotbeassignedanordinal./PlusInModule.def:warningLNK4222:exportedsymbol'DllRegisterServer'shouldnotbeassignedanordinal./PlusInModule.def:warningLNK4222:exportedsymbol'DllUnregisterServer'shouldnotbeassignedanordinal出現(xiàn)這個告警的原因是舊的項目的.def文件通常這樣定義ocx和com必需的四個導(dǎo)出函數(shù):EXPORTSDllCanUnloadNow@1PRIVATEDllGetClassObject@2PRIVATEDllRegisterServer@3PRIVATEDllUnregisterServer@4PRIVATE其中為這四個重要的導(dǎo)出函數(shù)指定了四個順序號。Windows平臺上通常用兩種方式定位DLL文件中的導(dǎo)出函數(shù),一種是根據(jù)導(dǎo)出函數(shù)名稱,一種是根據(jù)順序號,上學(xué)時曾經(jīng)寫過一個顯示圖片的程序,能處理大多數(shù)當(dāng)時流行的圖像格式文件,唯獨jpeg格式的搞不定,有一次看到一個圖像處理軟件中包含了一個LoadJpeg.dll,很顯然這個DLL是處理jpeg格式的圖像文件的嘛,于是趕快用dependslook了一下,頓時高喊:鬼啊~~~。原來這個depends竟然查不到導(dǎo)出函數(shù)的名字,后來才知道還有NONAME參數(shù)強(qiáng)制用順序號定位導(dǎo)出函數(shù),于是就常常弄個沒有導(dǎo)出函數(shù)名字的DLL到處show。。。。嗯,又扯遠(yuǎn)了。話說為什么舊的系統(tǒng)要以此指定這四個導(dǎo)出函數(shù)的順序號我就沒有研究了,反正現(xiàn)在不需要指定了,只要將@1,@2之類的刪除就行了,不過不刪好像也沒什么問題,它們會被自動忽略。六、使用MFC的消息映射宏引起的編譯錯誤錯誤現(xiàn)象之一:f:/project/...../plusmaindlg.cpp(220):errorC2440:'static_cast':cannotconvertfrom'void(__thiscallCPlusMainDlg::*)(int,BOOL)'to'LRESULT(__thiscallCWnd::*)(WPARAM,LPARAM)'Noneofthefunctionswiththisnameinscopematchthetargettype錯誤現(xiàn)象之二:f:/project/...../crpfileopavdlg.cpp(87):errorC2440:'static_cast':cannotconvertfrom'LRESULT(__thiscallCCrpFileOpavDlg::*)(LPCTSTR,int)'to'LRESULT(__thiscallCWnd::*)(WPARAM,LPARAM)'Noneofthefunctionswiththisnameinscopematchthetargettype以上兩個編譯錯誤產(chǎn)生是因為新舊版本的MFC中對ON_MESSAGE消息映射宏定義不同引起的,先看看老版本的MFC的ON_MESSAGE消息宏定義:#defineON_MESSAGE(message,memberFxn)/{message,0,0,0,AfxSig_lwl,/(AFX_PMSG)(AFX_PMSGW)(LRESULT(AFX_MSG_CALLCWnd::*)(WPARAM,LPARAM))&memberFxn},再看看新版本的ON_MESSAGE定義:#defineON_MESSAGE(message,memberFxn)/{message,0,0,0,AfxSig_lwl,/(AFX_PMSG)(AFX_PMSGW)/(static_cast<LRESULT(AFX_MSG_CALLCWnd::*)(WPARAM,LPARAM)>/(memberFxn))},注意,函數(shù)類型沒有變化,都是:LRESULT(AFX_MSG_CALLCWnd::*)(WPARAM,LPARAM);類型的函數(shù)指針(CWnd以及派生類的類成員函數(shù)指針),區(qū)別之處是新的ON_MESSAGE宏使用C++的static_cast操作符代替了C類型的強(qiáng)制轉(zhuǎn)換。產(chǎn)生這兩個錯誤其實是因為用戶沒有按照ON_MESSAGE宏的約定聲明和定義消息響應(yīng)函數(shù)造成的,比如,對于某些不需要處理返回值的消息響應(yīng)函數(shù),用戶通常這樣聲明和定義消息響應(yīng)函數(shù):在頭文件中聲明:afx_msgvoidOnFileProcess(WPARAMwParam,LPARAMlParam);在源文件中實現(xiàn):voidCCrpFileOpavDlg::OnFileProcess(WPARAMwParam,LPARAMlParam){.......}或者更過分一些,直接指定為實際參數(shù)類型:在頭文件中聲明:afx_msgvoidOnFileProcess(LPCTSTRlpszMessage,intnPercent);在源文件中實現(xiàn):voidCCrpFileOpavDlg::OnFileProcess(LPCTSTRlpszMessage,intnPercent){.......}舊版本的ON_MESSAGE使用了C類型的強(qiáng)制轉(zhuǎn)換,宏解開后的代碼后不會產(chǎn)生錯誤信息,但是改成對類型檢查很嚴(yán)格的static_cast操作符時就出問題了,因為通不過static_cast操作符的檢查。解決方法就是修改代碼,同時吸取教訓(xùn),普遍使用的方法并不一定就能約定俗成,一切還是要按照規(guī)矩來。錯誤現(xiàn)象之三:f:/project/...../WzButton.cpp(74):errorC2440:'static_cast':cannotconvertfrom'UINT(__thiscallCWzButton::*)(CPoint)'to'LRESULT(__thiscallCWnd::*)(CPoint)'Castfrombasetoderivedrequiresdynamic_castorstatic_cast出現(xiàn)這個錯誤的原因可是“人力不可抗拒”之原因造成的,因為舊版本的ON_WM_NCHITTEST宏使用了UINT(__thiscallCWzButton::*)(CPoint);類型的類成員函數(shù)指針,其定義如下:#defineON_WM_NCHITTEST()/{WM_NCHITTEST,0,0,0,AfxSig_wp,/(AFX_PMSG)(AFX_PMSGW)(UINT(AFX_MSG_CALLCWnd::*)(CPoint))&OnNcHitTest},但是新版本變成了:#defineON_WM_NCHITTEST()/{WM_NCHITTEST,0,0,0,AfxSig_l_p,/(AFX_PMSG)(AFX_PMSGW)/(static_cast<LRESULT(AFX_MSG_CALLCWnd::*)(CPoint)>(&ThisClass::OnNcHitTest))},注意返回值類型由UINT改成了LRESULT,再加上static_cast的嚴(yán)格檢查,所以就出錯了。修改的方法就是將你的OnNcHitTest函數(shù)由:afx_msgUINTOnNcHitTest(CPointpoint);改成:afx_msgLRESULTOnNcHitTest(CPointpoint);不必太在意,這個不是你的錯,不過,如果你要維護(hù)一個老的界面庫(通常很多控件的subclass都會用到ON_WM_NCHITTEST),改起來還是很痛苦地,不扯了,繼續(xù)下一個。七、statreg.cpp和atlimpl.cpp的廢棄(obsolete)問題在編譯老的ATL向?qū)傻拇a時,會遇到下面的編譯輸出:StdAfx.cppstatreg.cppisobsolete.Pleaseremoveitfromyourproject.atlimpl.cppisobsolete.Pleaseremoveitfromyourproject.因為老的ATL向?qū)傻拇a通常在stdafx.cpp文件中添加以下代碼:#ifdef_ATL_STATIC_REGISTRY#include<statreg.h>#include<statreg.cpp>#endif#include<atlimpl.cpp>根據(jù)提示刪除#include<statreg.cpp>和#include<atlimpl.cpp>兩行代碼就行了,不過更好的辦法是這樣改:#ifdef_ATL_STATIC_REGISTRY#include<statreg.h>#if_MSC_VER<=1200//MFC6.0orearlier#include<statreg.cpp>#endif#endif#if_MSC_VER<=1200//MFC6.0orearlier#include<atlimpl.cpp>#endif八、新的C++編譯器不再支持默認(rèn)類型的變量定義錯誤現(xiàn)象是:f:/project/...../WzCheckBox.cpp(464):errorC4430:missingtypespecifier-intassumed.Note:C++doesnotsupportdefault-int產(chǎn)生這個錯誤的原因是程序中出現(xiàn)了這樣的代碼:constsome_const_var=10;或staticsome_static_bool=FALSE;新的C++編譯器嚴(yán)格按照C++標(biāo)準(zhǔn),不再支持默認(rèn)類型的變量定義方式,必須嚴(yán)格指定變量類型,如下使用:constintsome_const_var=10;或staticBOOLsome_static_bool=FALSE;九、for語句的變量作用域問題考察下面的代碼:for(inti=0;i<120;i++){if(something_happen){break;}.............}if(i<120){//somethinghappen}在VC6的編譯器中,這樣的代碼是沒有問題的,因為VC6的編譯器為了兼容舊的MicrosoftC/C++編譯器,沒有嚴(yán)格按照C++標(biāo)準(zhǔn)執(zhí)行,但是從VC7開始,VC的編譯器開始遵守C++標(biāo)準(zhǔn),所以就會出現(xiàn)“變量i沒有定義的錯誤”。解決的方法也很簡單,按照J(rèn)imHyslop和HerbSutter的經(jīng)典對話系列的第四篇中的方法,改成如下就可以了:inti;for(i=0;i<120;i++)十、字符串函數(shù)的返回值問題strchr(_tcschr)、strpbrk(_tcspbrk??)、strrchr(_tcsrchr)和strstr(_tcsstr)這四個函數(shù)在VC6的CRT庫中定義的返回值都是char*(TCHAR*),所以以前的代碼通常是這樣使用的:TCHAR*cp=_tcschr(pszPath,_T('//'));//使用*cp,可以通過cp指針修改pszPath的內(nèi)容這其實是一個“漏洞”,因為如果pszPath是constchar(TCHAR)*字符串,那么就表示它不希望修改字符串的內(nèi)容,但是調(diào)用strchr(_tcschr)函數(shù)后就可以通過cp指針修改其內(nèi)容了,這豈不荒謬?所有在新版本的CRT庫中,這幾個函數(shù)的返回值都改成constchar*,這就會導(dǎo)致上面的代碼產(chǎn)生編譯錯誤。建議的修改方式是改成如下方式:constTCHAR*cp=_tcschr(pszPath,_T('//'));//不能再通過cp指針修改pszPath的內(nèi)容但是這樣修改可能對代碼的影響比較大,比如下面的代碼:TCHARbuf[256];//局部緩沖區(qū)......TCHAR*cp=_tcschr(buf,_T('//'));//作為局部緩沖區(qū)(非const),希望通過cp修改buf的內(nèi)容這種情況怎么辦呢?對了,C++還有個const_cast操作符,這時就可以排上用場了:TCHAR*cp=const_char<TCHAR*>(_tcschr(buf,_T('//')));不過上面的方法要慎用,除非確定buf是非const的,否則最好老老實實地修改代碼。十一、類成員函數(shù)指針做為函數(shù)參數(shù)的“C3867”錯誤考察下面的代碼,CWzWindowsHook類的構(gòu)造函數(shù)使用一個該類的成員函數(shù)指針,這樣構(gòu)造對象時可以選擇消息過濾的handler,可以是MouseMsgFilter,也可以是KeyboardMsgFilter:typedefBOOL(CWzWindowsHook::*FILTERPROC)(WPARAMwParam,LPARAMlParam);//Ahookusedincustomizationsheettofilterkeyboard/mouseeventsclassCWzWindowsHook{private:FILTERPROCm_pFilter;BOOLMouseMsgFilter(WPARAMwParam,LPARAMlParam);BOOLKeyboardMsgFilter(WPARAMwParam,LPARAMlParam);public:CWzWindowsHook(FILTERPROCpFilter):m_pFilter(pFilter)舊的遺留代碼存在這樣的用法:CWzWindowsHookmouseHooker(CWzWindowsHook::MouseMsgFilter);在VC6的編譯器下編譯可能沒有問題,但是在VC9的編譯器下編譯會有如下報錯:f:/project/...../WzWindowsHook.cpp(272):errorC3867:'CWzWindowsHook::MouseMsgFilter':functioncallmissingargumentlist;use'&CWzWindowsHook::MouseMsgFilter'tocreateapointertomember雖然C++從C繼承來了函數(shù)名即是函數(shù)地址的語法規(guī)則,但是根據(jù)C++的標(biāo)準(zhǔn),類成員函數(shù)的指針仍然需要一個取地址符“&”。解決方法很簡單,按照提示改成如下代碼即可:CWzWindowsHookmouseHooker(&CWzWindowsHook::MouseMsgFilter);十二、wchar_t*類型與USHORT*的轉(zhuǎn)換錯誤VC6的編譯器不支持wchar_t數(shù)據(jù)類型,wchar_t實際上被定義成unsignedshort,VC9的編譯器已經(jīng)支持wchar_t為內(nèi)置數(shù)據(jù)類型,但是由一個編譯選項控制,這個選項默認(rèn)是打開的,也就是將wchar_t作為編譯器的內(nèi)置數(shù)據(jù)類型。但是OLECHAR和WCHAR的定義仍然是unsignedshort,在VC6的編譯環(huán)境中,兩者的指針都是USHORT*,相互賦值和做為函數(shù)參數(shù)傳遞沒有問題,但是如果wchar_t作為編譯器的內(nèi)置數(shù)據(jù)類型,那就意味著wchar_t*與OLECHAR*或WCHAR*是兩種不同類型的指針,相互賦值就會報編譯錯誤,下面的信息就是一個典型的錯誤輸出:f:/project/...../shellpidl.cpp(290):errorC2664:'MultiByteToWideChar':cannotconvertparameter5from'USHORT*'to'LPWSTR'Typespointedtoareunrelated;conversionrequiresreinterpret_cast,C-stylecastorfunction-stylecast解決的方法就是使用C++的reinterpret_cast操作符或使用C-style強(qiáng)制轉(zhuǎn)換,當(dāng)然也可以在項目屬性設(shè)置中關(guān)閉前面提到的那個選項(這個偶美試過,不知道會不會有其它問題)。編譯時出現(xiàn)“operator+=”不明確,也就是StringData+=nChar;改正方法:pDoc->StringData+=(char)nChar,因為系統(tǒng)里面存在一個wchar_t的類型,所以如果支持了這個類型的話,從unsignednt轉(zhuǎn)換到wchar_t和char的等級都是標(biāo)準(zhǔn)轉(zhuǎn)換,所以編譯器無法判斷到底應(yīng)該轉(zhuǎn)換到哪一個,故而導(dǎo)致了這個問題 intx1=m_strLine.Find(''); CStringy1=_T(""); y1.Format(_T("%d"),x1); MessageBox(y1); CString轉(zhuǎn)int
CStringb="123";
inti;
i=_ttoi(b);//在使用多字符集下_atoi(arraytointeger的縮寫)函數(shù)是一個好的選擇,它也很少會是一個正確的選擇。而在使用Unicode字符,你應(yīng)該用_ttoi(),它在ANSI編碼系統(tǒng)中被編譯成_atoi()int型轉(zhuǎn)CString型
CStringa;
intb=20;
a.Format(_T("%d"),b);//_T宏可以把一個引號引起來的字符串,根據(jù)你的環(huán)境設(shè)置,使得編譯器會根據(jù)編譯目標(biāo)環(huán)境選擇合適的(Unicode還是ANSI)字符處理方式,TEXT,_TEXT和_T是一樣的CString型轉(zhuǎn)double型
CStringstrs;
doublef;
f=_ttol(strs);CString型轉(zhuǎn)float型
CStringstrs;
floatflt;
flt=(float)atof((char*)(LPTSTR)(LPCTSTR)strs);===============================================================================CString,char*,const
char
*,LPCTSTR
的轉(zhuǎn)換
如何將CString類型的變量賦給char*類型的變量
1、GetBuffer函數(shù):
使用CString::GetBuffer函數(shù)。
char*p;
CStringstr="hello";
p=str.GetBuffer(str.GetLength());
str.ReleaseBuffer();將CString轉(zhuǎn)換成char*時
CStringstr("aaaaaaa");
strcpy(str.GetBuffer(10),"aa");
str.ReleaseBuffer();
當(dāng)我們需要字符數(shù)組時調(diào)用GetBuffer(intn),其中n為我們需要的字符數(shù)組的長度.使用完成后一定要馬上調(diào)用ReleaseBuffer();
還有很重要的一點就是,在能使用constchar*的地方,就不要使用char*2、memcpy:
CStringmCS=_T("cxl");
charmch[20];
memcpy(mch,mCS,20);3、用LPCTSTR強(qiáng)制轉(zhuǎn)換:盡量不使用
char*ch;
CStringstr;
ch=(LPSTR)(LPCTSTR)str;CStringstr="good";
char*tmp;
sprintf(tmp,"%s",(LPTSTR)(LPCTSTR)str);4、
CStringMsg;
Msg=Msg+"abc";
LPTSTRlpsz;
lpsz=newTCHAR[Msg.GetLength()+1];
_tcscpy(lpsz,Msg);
char*psz;
strcpy(psz,lpsz);
CString類向constchar*轉(zhuǎn)換
chara[100];
CStringstr("aaaaaa");
strncpy(a,(LPCTSTR)str,sizeof(a));
或者如下:
strncpy(a,str,sizeof(a));
以上兩種用法都是正確地.因為strncpy的第二個參數(shù)類型為constchar*.所以編譯器會自動將CString類轉(zhuǎn)換成constchar*.CString轉(zhuǎn)LPCTSTR(constchar*)
CStringcStr;
constchar*lpctStr=(LPCTSTR)cStr;LPCTSTR轉(zhuǎn)CString
LPCTSTRlpctStr;
CStringcStr=lpctStr;將char*類型的變量賦給CString型的變量
可以直接賦值,如:
CStringmyString="Thisisatest";
也可以利用構(gòu)造函數(shù),如:
CStrings1("Tom");將CString類型的變量賦給char[]類型(字符串)的變量
1、sprintf()函數(shù)
CStringstr="good";
chartmp[200];
sprintf(tmp,"%s",(LPCSTR)str);
(LPCSTR)str這種強(qiáng)制轉(zhuǎn)換相當(dāng)于(LPTSTR)(LPCTSTR)str
CString類的變量需要轉(zhuǎn)換為(char*)的時,使用(LPTSTR)(LPCTSTR)str然而,LPCTSTR是constchar*,也就是說,得到的字符串是不可寫的!將其強(qiáng)制轉(zhuǎn)換成LPTSTR去掉const,是極為危險的!
一不留神就會完蛋!要得到char*,應(yīng)該用GetBuffer()或GetBufferSetLength(),用完后再調(diào)用ReleaseBuffer()。2、strcpy()函數(shù)
CStringstr;
charc[256];
strcpy(c,str);charmychar[1024];
CStringsource="Hello";
strcpy((char*)&mychar,(LPCTSTR)source);
UNICODE下寬字符的CString轉(zhuǎn)換為constchar*一、使用函數(shù)_tcscpy_s:CStringtheString("Thisisatest");
int
sizeOfString=(theString.GetLength()+1);
LPTSTR
lpsz=newTCHAR[sizeOfString];
_tcscpy_s(lpsz,sizeOfString,theString);最后再轉(zhuǎn)換一下lpsz為const型的LPTSTR在UNICODE環(huán)境下編譯是wchar_t類型
二、CStringstr=_T("HelloWorld!");charszStr[256]={0};wcstombs(szStr,str,str.GetLength());constchar*p=szStr;
if($!=jQuery){$=jQuery.noConflict();}================================================= intnum1,num2,num3; TCHARch1[10],ch2[10],ch3[10]; GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10); GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,10); num1=_ttoi(ch1); num2=_ttoi(ch2); num3=num1+num2; _itot(num3,ch3,10); GetDlgItem(IDC_EDIT3)->SetWindowText(ch3); intx1=m_strLine.Find(''); CStringy1=_T(""); y1.Format(_T("%d"),x1); MessageBox(y1); 你好,你的理解大體上是正確的。你拿過pDC來用,讓它給你輸出你設(shè)置的字體,但是用完以后,是要歸還的,還要把它設(shè)置成原來那個字體,不然之前調(diào)用pDC的地方就會還按這個字體輸出文字了。解釋如下CFont*pOldFont=pDC->SelectObject(&m_font);//保留原來的字體指針到pOldFont中。(SelectObject這個函數(shù)會返回原有指針)pDC->TextOut(0,0,m_fontname);//輸出你的字體的文字pDC->SelectObject(pOldFont);//設(shè)置pDC到原有字體指針如何為工具欄添加單獨的響應(yīng)函數(shù)?要改三個地方
在view或者doc類里類函數(shù)里面添加類似
afx_msgvoidOnButtonZoomIn();//函數(shù)聲明
在其cpp中添加關(guān)聯(lián)
ON_COMMAND(ID_BUTTON_ZOOMIN,&CScaleMapView::OnButtonZoomIn)
最后添加函數(shù)
voidCScaleMapView::OnButtonZoomIn()//函數(shù)實現(xiàn)
{
}CToolBar:----DockControlBar();
CMFCToolBar:DockPane()不能轉(zhuǎn)換void(_thiscallCMainFrame::*)(void)toLRESULT(__thiscallCWnd::*)(WPARAM,LPARAM)開發(fā)平臺由VC6.0升級至VS2005,需要將原有的項目遷移??赡芘龅筋愃棋e誤:
errorC2440:'static_cast':cannotconvertfrom'void(__thiscallCMainFrame::*)
(void)'to'LRESULT(__thiscallCWnd::*)(WPARAM,LPARAM)'
VS2005對消息的檢查更為嚴(yán)格,以前在VC6下完全正常運(yùn)行的消息映射在VS2005下編譯不通過
ON_MESSAGE(WM_message,OnMyMessage);
OnMyMessage返回值必須為LRESULT,其形式為:afx_msgLRESULTOnMyMessage(WPARAM,LPARAM);如果不符合,則有錯誤提示:
errorC2440:“static_cast”:無法從“void(__thiscallCPppView::*)(WPARAM,LPARAM)”轉(zhuǎn)換為“LRESULT(__thiscallCWnd::*)(WPARAM,LPARAM)”在匹配目標(biāo)類型的范圍內(nèi)沒有具有該名稱的函數(shù)
errorC2440:“static_cast”:無法從“void(__thiscallCPppView::*)
(void)”轉(zhuǎn)換為“LRESULT(__thiscallCWnd::*)(WPARAM,LPARAM)”在匹配目標(biāo)類型的范圍內(nèi)沒有具有該名稱的函數(shù)
解決方法如下:例如:TransparentWnd.cpp中ON_MESSAGE(WM_LIBEN,OnLiben):第一:把原來的消息函數(shù)返回值類型改為LRESULT(找到OnLiben定義,如Viod
CTransparentWnd::OnLiben(WPARAMwParam,LPARAMlParam)改成LRESULTCTransparentWnd::OnLiben(WPARAMwParam,LPARAMlParam),聲明處也要改,如afx_msgLRESULTOnLiben(WPARAMwParam,LPARAMlParam););第二:函數(shù)內(nèi)可以隨便寫個returnTRUE;第三:然后消息函數(shù)的參數(shù)必須改寫成(WPARAMwParam,LPARAMlParam)而不論這兩個參數(shù)是否用得到;第四:消息映射如ON_MESSAGE(WM_message,&OnMyMessage下面是古文鑒賞,不需要的朋友可以下載后編輯刪除??!謝謝??!九歌·湘君
屈原
朗誦:路英
君不行兮夷猶,蹇誰留兮中洲。
美要眇兮宜修,沛吾乘兮桂舟。
令沅湘兮無波,使江水兮安流。
望夫君兮未來,吹參差兮誰思。
駕飛龍兮北征,邅吾道兮洞庭。
薜荔柏兮蕙綢,蓀橈兮蘭旌。
望涔陽兮極浦,橫大江兮揚(yáng)靈。
揚(yáng)靈兮未極,女嬋媛兮為余太息。
橫流涕兮潺湲,隱思君兮陫側(cè)。
桂棹兮蘭枻,斫冰兮積雪。
采薜荔兮水中,搴芙蓉兮木末。
心不同兮媒勞,恩不甚兮輕絕。
石瀨兮淺淺,飛龍兮翩翩。
交不忠兮怨長,期不信兮告余以不閑。
朝騁騖兮江皋,夕弭節(jié)兮北渚。她含著笑,切著冰屑悉索的蘿卜,
她含著笑,用手掏著豬吃的麥糟,
她含著笑,扇著燉肉的爐子的火,
她含著笑,背了團(tuán)箕到廣場上去
曬好那些大豆和小麥,
大堰河,為了生活,
在她流盡了她的乳液之后,
她就用抱過我的兩臂,勞動了。
大堰河,深愛著她的乳兒;
在年節(jié)里,為了他,忙著切那冬米的糖,
為了他,常悄悄地走到村邊的她的家里去,
為了他,走到她的身邊叫一聲“媽”,
大堰河,把他畫的大紅大綠的關(guān)云長
貼在灶邊的墻上,
大堰河,會對她的鄰居夸口贊美她的乳兒;
大堰河曾做了一個不能對人說的夢:
在夢里,她吃著她的乳兒的婚酒,
坐在輝煌的結(jié)彩的堂上,
而她的嬌美的媳婦親切的叫她“婆婆”
…………
大堰河,深愛她的乳兒!
大堰河,在她的夢沒有做醒的時候已死了。
她死時,乳兒不在她的旁側(cè),
她死時,平時打罵她的丈夫也為她流淚,
五個兒子,個個哭得很悲,
她死時,輕輕地呼著她的乳兒的名字,
大堰河,已死了,
她死時,乳兒不在她的旁側(cè)。
大堰河,含淚的去了!
同著四十幾年的人世生活的凌侮,
同著數(shù)不盡的奴隸的凄苦,
同著四塊錢的棺材和幾束稻草,
同著幾尺長方的埋棺材的土地,
同著一手把的紙錢的灰,
大堰河,她含淚的去了。
這是大堰河所不知道的:
她的醉酒的丈夫已死去,
大兒做了土匪,
第二個死在炮火的煙里,
第三,第四,第五
而我,我是在寫著給予這不公道的世界的咒語。
當(dāng)我經(jīng)了長長的飄泊回到故土?xí)r,
在山腰里,田野上,
兄弟們碰見時,是比六七年
鳥次兮屋上,水周兮堂下。
捐余玦兮江中,遺余佩兮澧浦。
采芳洲兮杜若,將以遺兮下女。
時不可兮再得,聊逍遙兮容與。
注釋
①湘君:湘水之神,男性。一說即巡視南方時死于蒼梧的舜。
②君:指湘君。夷猶:遲疑不決。
③蹇(jian3簡):發(fā)語詞。洲:水中陸地。
④要眇(miao3秒):美好的樣子。宜修:恰到好處的修飾。
⑤沛:水大而急。桂舟:桂木制成的船。
⑥沅湘:沅水和湘水,都在湖南。無波:不起波浪。
⑦夫:語助詞。
⑧參差:高低錯落不齊,此指排簫,相傳為舜所造。
⑨飛龍:雕有龍形的船只。北征:北行。
⑩邅(zhan1沾):轉(zhuǎn)變。洞庭:洞庭湖。
⑾薜荔:蔓生香草。柏(bo2伯):通“箔”,簾子。蕙:香草名。綢:帷帳。
⑿蓀:香草,即石菖蒲。橈(rao2饒):短槳。蘭:蘭草:旌:旗桿頂上的飾物。
⒀涔(cen2岑)陽:在涔水北岸,洞庭湖西北。極浦:遙遠(yuǎn)的水邊。
⒁橫:橫渡。揚(yáng)靈:顯揚(yáng)精誠。一說即揚(yáng)舲,揚(yáng)帆前進(jìn)。
⒂極:至,到達(dá)。
⒂女:侍女。嬋媛:眷念多情的樣子。
⒃橫:橫溢。潺湲(yuan2援):緩慢流動的樣子。
⒅陫(pei2培)側(cè):即“悱惻”,內(nèi)心悲痛的樣子。
(19)櫂(zhao4棹):同“棹”,長槳。枻(yi4弈):短槳。
(20)斲(zhuo2琢):砍。
(21)搴(qian1千):拔取。芙蓉:荷花。木末:樹梢。
(22)媒:媒人。勞:徒勞。
(23)甚:深厚。輕絕:輕易斷絕。
(24)石瀨:石上急流。淺(jian1間)淺:水流湍急的樣子。
(25)翩翩:輕盈快疾的樣子。
(26)交:交往。
(27)期:相約。不閑:沒有空閑。
(28)鼂(zhao1招):同“朝”,早晨。騁騖(wu4務(wù)):急行。皋:水旁高地。
(29)弭(mi3米):停止。節(jié):策,馬鞭。渚:水邊。
(30)次:止息。(31)周:周流。
(32)捐:拋棄。玦(jue1決):環(huán)形玉佩。
(33)遺(yi2儀):留下。佩:佩飾。醴(li3里):澧水,在湖南,流入洞庭湖。
(34)芳洲:水中的芳草地。杜若:香草名。
(35)遺(wei4味):贈予。下女:指身邊侍女。
(36)聊:暫且。容與:舒緩放松的樣子。
譯文
君不行兮夷猶,
神君遲疑猶豫徘徊不肯向前,
蹇誰留兮中洲?
你為誰滯留在水中的島上呢?
美要眇兮宜修,
我容顏妙麗裝飾也恰倒好處,
沛吾乘兮桂舟。
急速地乘坐上我那桂木小舟。
令沅、湘兮無波,
叫沅湘之水柔媚得波瀾不生,
使江水兮安流。
讓長江之水平靜地緩緩前行。
望夫君兮未來,
盼望著你啊你為何還不到來,
吹參差兮誰思!
吹起洞簫寄托我的思念之情!
駕飛龍兮北征,
用飛龍駕舟急速地向北行駛,
邅吾道兮洞庭。
改變我的道路引舟直達(dá)洞庭。
薜荔柏兮蕙綢,
用薜荔做門簾用蕙草做床帳,
蓀橈兮蘭旌。
以香蓀裝飾船槳以蘭草為旗。
望涔陽兮極浦,
遙望涔陽啊在那遼遠(yuǎn)的水邊,
橫大江兮揚(yáng)靈。
大江橫陳面前彰顯你的威靈。
揚(yáng)靈兮未極,
難道你的威靈彰顯還沒終止?
女嬋媛兮為余太息!
我心中為你發(fā)出長長的嘆息。
橫流涕兮潺湲,
眼中的清淚似小溪潺潺流下,
隱思君兮陫側(cè)。
暗地里思念你心中充滿悲傷。
桂棹兮蘭枻,
想用桂木作成槳蘭木作成舵,
斫冰兮積雪。
劈開你堅冰積雪也似的情懷。
采薜荔兮水中,
卻似在水中采集陸生的薜荔,
搴芙蓉兮木末。
更似爬樹梢采摘水生的芙蓉。
心不同兮媒勞,
兩心不相通讓媒妁徒勞無功,
恩不甚兮輕絕。
恩愛不深切就會輕易的斷絕。
石瀨兮淺淺,
留連著沙石灘上淺淺的流水,
飛龍兮翩翩。
等待著你駕著飛龍翩然降臨。
交不忠兮怨長,
你交情不忠徒增我多少幽怨,
期不信兮告余以不間。
既相約又失信卻說沒有時間。
朝騁騖兮江皋,
早晨我駕車在江邊急急奔馳,
夕弭節(jié)兮北渚。
晚間我停鞭在北岸灘頭休息。
鳥次兮屋上,
眾鳥棲息在這空閑的屋頂上,
水周兮堂下。
空屋的四周有流水迂緩圍繞。
捐余玦兮江中,
將你贈的玉制扳指置于江中,
遺余佩兮澧浦。
將你贈的玉佩放在澧水岸邊。
采芳洲兮杜若,
采來香草裝飾這芬芳的洲瀆,
將以遺兮下女。
這一切都是你留給我的信物。
時不可兮再得,
難道那往昔的時光不可再得,
聊逍遙兮容與。
暫且慢步洲頭排除心中煩惱。
賞析
在屈原根據(jù)楚地民間祭神曲創(chuàng)作的《九歌》中,《湘君》和《湘夫人》是兩首最富生活情趣和浪漫色彩的作品。人們在欣賞和贊嘆它們獨特的南國風(fēng)情和動人的藝術(shù)魅力時,卻對湘君和湘夫人的實際身份迷惑不解,進(jìn)行了長時間的探討、爭論。
從有關(guān)的先秦古籍來看,盡管《楚辭》的《遠(yuǎn)游》篇中提到“二女”和“湘靈”,《山海經(jīng)·中山經(jīng)》中說“洞庭之山……帝之二女居之,是常游于江淵”,但都沒有像后來的注釋把湘君指為南巡道死的舜、把湘夫人說成追趕他而溺死湘水的二妃娥皇和女英的跡象。最初把兩者結(jié)合在一起的是《史記·秦始皇本紀(jì)》。書中記載秦始皇巡游至湘山(即今洞庭湖君山)時,“上問博士曰:‘湘君何神?’博士對曰:‘聞之,堯女,舜之妻,而葬此?!焙髞韯⑾虻摹读信畟鳌芬舱f舜“二妃死于江、湘之間,俗謂之湘君”。這就明確指出湘君就是舜的兩個妃子,但未涉及湘夫人。到了東漢王逸為《楚辭》作注時,鑒于二妃是女性,只適合于湘夫人,于是便把湘君另指為“湘水之神”。對于這種解釋。唐代韓愈并不滿意,他在《黃陵廟碑》中認(rèn)為湘君是娥皇,因為是正妃故得稱“君”;女英是次妃,因稱“夫人”。以后宋代洪興祖《楚辭補(bǔ)注》、朱熹《楚辭集注》皆從其說。這一說法的優(yōu)點在于把湘君和湘夫人分屬兩人,雖避免了以湘夫人兼指二妃的麻煩,但仍沒有解決兩人的性別差異,從而為詮釋作品中顯而易見的男女相戀之情留下了困難。有鑒于此,明末清初的王夫之在《楚辭通釋》中采取了比較通脫的說法,即把湘君說成是湘水之神,把湘夫人說成是他的配偶,而不再拘泥于按舜與二妃的傳說一一指實。應(yīng)該說這樣的理解,比較符合作品的實際,因而也比較可取。
雖然舜和二妃的傳說給探求湘君和湘夫人的本事帶來了不少難以自圓的穿鑿附會,但是如果把這一傳說在屈原創(chuàng)作《九歌》時已廣為流傳、傳說與創(chuàng)作的地域完全吻合、《湘夫人》中又有“帝子”的字樣很容易使人聯(lián)想到堯之二女等等因素考慮在內(nèi),則傳說的某些因子如舜與二妃飄泊山川、會合無由等,為作品所借鑒和吸取也并不是沒有可能的。因此既注意到傳說對作品可能產(chǎn)生的影響,又不拘泥于傳說的具體人事,應(yīng)該成為我們理解和欣賞這兩篇作品的基點。
由此出發(fā),不難看出作為祭神歌曲,《湘君》和《湘夫人》是一個前后相連的整體,甚至可以看作同一樂章的兩個部分。這不僅是因為兩篇作品都以“北渚”相同的地點暗中銜接,而且還由于它們的末段,內(nèi)容和語意幾乎完全相同,以至被認(rèn)為是祭祀時歌詠者的合唱(見姜亮夫《屈原賦校注》)。
這首《湘君》由女神的扮演者演唱,表達(dá)了因男神未能如約前來而產(chǎn)生的失望、懷疑、哀傷、埋怨的復(fù)雜感情。第一段寫美麗的湘夫人在作了一番精心的打扮后,乘著小船興致勃勃地來到與湘君約會的地點,可是卻不見湘君前來,于是在失望中抑郁地吹起了哀怨的排簫。首二句以問句出之,一上來就用心中的懷疑揭出愛而不見的事實,為整首歌的抒情作了明確的鋪墊。以下二句說為了這次約會,她曾進(jìn)行了認(rèn)真的準(zhǔn)備,把本已姣好的姿容修飾得恰到好處,然后才駕舟而來。這說明她十分看重這個見面的機(jī)會,內(nèi)心對湘君充滿了愛戀。正是在這種心理的支配下,她甚至虔誠地祈禱沅湘的江水風(fēng)平浪靜,能使湘君順利赴約。然而久望之下,仍不見他到來,便只能吹起聲聲幽咽的排簫,來傾吐對湘君的無限思念。這一段的描述,讓人看到了一幅望斷秋水的佳人圖。
第二段接寫湘君久等不至,湘夫人便駕著輕舟向北往洞庭湖去尋找,忙碌地奔波在湖中江岸,結(jié)果依然不見湘君的蹤影。作品在這里把對湘夫人四出尋找的行程和她的內(nèi)心感受緊密地結(jié)合在一起。你看她先是駕著龍舟北出湘浦,轉(zhuǎn)道洞庭,這時她顯然對找到湘君滿懷希望;可是除了眼前浩渺的湖水和裝飾精美的小船外,一無所見;她失望之余仍不甘心,于是放眼遠(yuǎn)眺涔陽,企盼能捕捉到湘君的行蹤;然而這一切都毫無結(jié)果,她的心靈便再次橫越大江,遍尋沅湘一帶的廣大水域,最終還是沒有找到。如此深情的企盼和如此執(zhí)著的追求,使得身邊的侍女也為她嘆息起來。正是旁人的這種嘆息,深深地觸動和刺激了湘夫人,把翻滾在她內(nèi)心的感情波瀾一下子推向了洶涌澎湃的高潮,使她止不住淚水縱橫,一想起湘君的失約就心中陣陣作痛。
第三段主要是失望至極的怨恨之情的直接宣泄。首二句寫湘夫人經(jīng)多方努力不見湘君之后,仍漫無目的地泛舟水中,那如劃開冰雪的船槳雖然還在擺動,但給人的感覺只是她行動的遲緩沉重和機(jī)械重復(fù)。接著用在水中摘采薜荔和樹上收取芙蓉的比喻,既總結(jié)以上追求不過是一種徒勞而已,同時也為后面對湘君“心不同”、“恩不甚”、“交不忠”、“期不信”的一連串斥責(zé)和埋怨起興。
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 專業(yè)勞務(wù)輸出承包協(xié)議范本版B版
- 2024水塔拆除及拆除現(xiàn)場消防安全隱患排查合同3篇
- 2024幼兒園保育員幼兒早期教育與家庭教育合作合同3篇
- 專項粉刷施工合作合同2024版版B版
- 2023-2024學(xué)年滬科版(2019)高中信息技術(shù)必修二第二單元項目四《探索電子點餐信息系統(tǒng)軟件-了解軟件的功能和開發(fā)》說課稿
- 2024年碎石資源開采與購銷合同協(xié)議書3篇
- 2025彩鋼板復(fù)合材料研發(fā)與應(yīng)用合作協(xié)議3篇
- 11別傷著自己(說課稿)-部編版道德與法治一年級上冊
- 中醫(yī)跟師心得(四氣調(diào)神)
- 市第五醫(yī)院醫(yī)學(xué)倫理標(biāo)準(zhǔn)操作規(guī)程和審查指南
- 如何避免護(hù)理患者投訴
- 浙江省省杭州市上城區(qū)建蘭中學(xué)2023-2024學(xué)年八年級數(shù)學(xué)第一學(xué)期期末調(diào)研模擬試題含解析
- 你比我猜成語
- 中醫(yī)常用診療技術(shù)實訓(xùn)指導(dǎo)
- 異質(zhì)結(jié)完整分
- 華為經(jīng)營管理-華為的流程管理(6版)
- 膿毒癥1小時bundle質(zhì)量控制
- 第7講 高斯光束的聚焦和準(zhǔn)直課件
- 二、問題解決型(指令性目標(biāo))QC成果案例
- 骨科患者術(shù)后疼痛管理的新進(jìn)展
- 小學(xué)生三好學(xué)生競選演講稿PPT幻燈片
評論
0/150
提交評論