基於IE核心的多媒體檔案視覺化程式實現(二)
文章目錄
上回說道,我們需要使用命令列引數方法將要瀏覽的檔名傳入wsee.exe 程式,然後由
OnInitialUpdate()
函式中呼叫
Navigate2
實現利用IE核心解析檔案,最後顯示出檔案內容來。然而,
Navigate2
函式只接受絕對路徑的檔案訪問,所以要進行輸入字串的轉換。
先解決第1個問題:如何利用命令列引數將要瀏覽的檔名傳入?
使用命令列引數
在C語言中(後來的java、python等也如此),命令列引數是以帶引數的main函式完成的(以argv傳遞引數的個數,以argc字串陣列傳遞各引數的具體字串。
然而,MFC對此也進行了封裝,說不清好還是壞,反正用了MFC,你就得按MFC的規矩來做,上了賊船,得行賊道。查MFC用法,又提供了好幾種方法,顯然,上了MFC船的C++已經不是原來的伊人。
開啟上次所建的wsee工程,從CWseeApp::InitInstance()
函式中可見到:
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
可見MFC定義了新的物件cmdInfo
,以ParseCommandLine(cmdInfo)
進行命令列引數的解釋,然後送以函式ProcessShellCommand(cmdInfo)
實行處理,從而完成開啟檔案的預設行為。這樣,使用者不必編寫新的程式碼,就能對命令列引數的所指出的檔案做預設處理(例如,等價於選單中的檔案|開啟項)。
但現在我需要依據檔名直接(或做解析變換後)送入Navigate2
函式,顯然要寫新的程式碼了。
又查得,MFC訪問命令列引數有三種方法:
1、包含程式本身全路徑和命令列引數
::GetCommandLine();
2、使用巨集,依次獲取每一個命令列引數
__argc, __argv[],
3、僅獲取命令列引數
AfxGetApp()->m_lpCmdLine;
其中,第2種方法與傳統C語言的方法形式上最接近,看來還有點伊人的影子!就用這個吧,在void CWseeView::OnInitialUpdate()
函式中去寫程式碼。
我們說,程式是演化出來的,先加一句訊息框輸出__argv[1]
的內容。在傳統C語言中,除錯程式時我們常常用printf將訊息字串列印到螢幕上來看,在windows程式除錯中,我們也用訊息框來輸出訊息並暫停程式。如下。注意取命令列引數時應先用if語句判斷一下輸入引數的個數。以免取空。
void CWseeView::OnInitialUpdate()
{
CHtmlView::OnInitialUpdate();
if(__argc>2){
AfxMessageBox(__argv[1]);
AfxMessageBox(__argv[2]);
}
Navigate2(_T("http://www.baidu.com/"),NULL,NULL);
}
編譯程式後,由於是帶引數的,就不要直接在VC++整合環境中點圖示執行,而要進入編譯生成的exe檔案路徑,以命令列方式進行。如下:
-
不帶引數情況:
程式直接執行顯示出Navigate2
函式所指的百度網頁。 -
帶一個引數或多個引數,MFC這樣處理引數(
__argv[1]
到__argv[n]
):- 如果這個引數是以減號
-
或/
起頭,則認為是選項引數。 - 如果這個引數是以其他符號起頭,則視為要開啟的檔案,由 函式
ProcessShellCommand(cmdInfo)
判別是否檔案存在,如不存在,則直接提示後退出。如存在,則進行預設處理(不處理,由程式設計師程式碼定)。
- 如果這個引數是以減號
例如: 執行wsee abc
則彈出訊息框說abc檔案找不到。
執行wsee wsee.obj
則直接執行,顯示百度網頁:
執行wsee -w
也如上顯示百度網頁。
執行wsee -w -www.abc.com
(wsee /w /www.abc.com
也可)則順序彈出兩訊息框:
說明引數傳入與我們的想法一致。
接下來對傳輸的引數進行處理就可。
引數格式設計為:
-
如無引數,則顯示幫助資訊。
-
通過第1個引數傳遞檔名或網址,其他引數項直接丟棄。
- 如果引數以減號
-
或/
號起頭,則認為是http網址,傳入後將首字元(減號或/
號)去掉送Navigate2
函式即可。 - 如果引數以其他字元起頭,則認為是本地檔案。如檔案存在,則將其轉換這絕對路徑送
Navigate2
函式。 - 對於本地檔案,判斷如是絕對路徑的,則直接送
Navigate2
函式。絕對路徑的標誌是:第2字元為:
冒號。如d:\\xxx\\yyy\\zzz.png
或d:/xxx/yyy/zzz.png
。【注:C語言中,\
要用\\
來轉義,而可直接用/
。】 - 相對路徑如:當前路徑(即只有檔名),子目錄路徑,如
./yyy/zzz.png
,上一級目錄../pp/qq.jpg
。如此類推。
- 如果引數以減號
命令列引數獲取和解析程式碼
【程式碼說明】:對於字串的處理,MFC給出了比C語言更方便的CString類。這裡,為了說明用純C語言簡單字串函式也能完成任務,我們沒有選擇使用CString類,而是直接用char *
來定義字串。用GetCurrentDirectory
函式來獲取當前工作目錄。用GetModuleFileName
函式來獲取wsee.exe所在目錄,從而找到同目錄下的幫助檔案help.htm
。
程式碼:修改OnInitialUpdate()
函式如下:
void CWseeView::OnInitialUpdate()
{
CHtmlView::OnInitialUpdate();
char str[256];
char chCurtPath[256];//當前工作目錄
char path[256];//本軟體wsee.exe所在目錄
char *ptr;
int len;
GetCurrentDirectory(256,chCurtPath);//獲取當前目錄,並存在chCurtPath中
len=strlen(chCurtPath);//計算路徑字串長度
if(chCurtPath[len-1]==0x5c)
{
//0x5c是'\',如串中有'\'則去掉,如'd:\'
chCurtPath[len-1]=0;//去掉串中最後的'\'
}
if(__argc>1)
{
char *input=__argv[1];
if(input[1]==0x3a)
{//判斷是否為絕對路徑。絕對路徑的第2個字元是冒號(0x3a)
str[0]=0;
strcat(str,__argv[1]);//絕對路徑則直接使用
}
else if(input[0]!=0x2d && input[0]!=0x2f)//利用相對路徑構造絕對路徑
{
str[0]=0;//初始化
strcat(str,chCurtPath);
strcat(str,"\\");
strcat(str,__argv[1]);
//AfxMessageBox(__argv[1]); //測試用
}else
{
//如有選項符(-或/),則將字串當做網址處理
str[0]=0;
strcat(str,__argv[1]+1);//+1就是去掉字串中第1個字元(-或/)
//AfxMessageBox(str); //測試用
}
Navigate2(str,NULL,NULL);
}
else
{
//如無引數,則顯示幫助文件help.html
GetModuleFileName(NULL,path,256);
ptr=strrchr(path, '\\');
path[ptr-path]=0;//截斷,只留exe所在路徑
strcat(path,"/help.htm");
//path為絕對路徑,指向exe所在資料夾的help.htm檔案
Navigate2(path,NULL,NULL);//顯示幫助資訊
}
}
這樣,新增程式碼在50行左右,基本實現了需求功能。
幫助系統
可編寫軟體的使用手冊文件。這裡,我採用了簡單的htm格式書寫,命名help.html,並置於與wsee.exe同文件路徑中(GetModuleFileName函式就是為了在無引數執行wsee時找到該幫助文件並開啟)。有了html格式支援,幫助文件風格和內容可以是極其豐富和自由的。例如,可以直接連結到開發者網頁或軟體更新網址。現代版本的MATLAB、VS2017等等軟體都傾向於將系統手冊直接置於產品網站上,這樣可隨時更新。
例如,我們的幫助文件寫為:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>wsee 一個簡單的圖片檔案檢視器 V0.1</title>
</head>
<body>
<h1>WSEE 幫助文件</h1>
<p>一個簡單的圖片檔案檢視器 V0.1</p>
<a href="http://www.wtclab.net">昆明理工大學無線通訊團隊 WTCLAB(R)2018</a>
<h2>用法</h2>
<h3>一、顯示本幫助文件</h3>
<p> wsee 【回車】 顯示本幫助</p>
<h3>二、顯示本地圖片檔案</h3>
<p> wsee 圖片檔名【回車】 顯示圖片</p>
<p>如:</p>
<pre>
wsee xxx.png
wsee d:\xxx\yyy\zzz.png
wsee ..\zzz.png
wsee ..\kk\zzz.png
wsee .\qq\zzz.png
</pre>
<p>圖片格式為:png,gif動畫,jpg,bmp,svg,ico,pdf...</p>
1. 點陣圖格式:bmp,png,jpg,ico,...<p>
2. 動畫格式:gif <p>
3. 向量圖格式:svg,emf,wmf, pdf, <p>
<h3>三、顯示網際網路網站</h3>
(這是附加功能,僅供測試,不夠完善)
<p>wsee 採用-或/選項,後接網址</p>
<p>如:</p>
<pre>
wsee -www.baidu.com
wsee /www.wtclab.net
wsee -http://www.wtclab.net/newwtc/engineertrianing.php
</pre>
又如:用百度、有道查詞
<pre>
wsee -https://www.baidu.com/baidu?word=無線通訊團隊
wsee -https://www.baidu.com/s?wd=CSDN%20C語言
wsee -http://www.youdao.com/w/字典
</pre>
<h3>四、操作</h3>
只要IE瀏覽器能顯示的,這個就能顯示。
<p> Ctrl+ 滑鼠滾輪可縮放頁面</p>
</body>
</html>
這樣,直接執行wsee.exe
,將顯示:
執行測試
將wsee.exe編譯好,放在任意資料夾位置,並將該位置新增到系統環境變數path
路徑中。這樣,在任何工作目錄下就都能找到wsee.exe來運行了。
設當前路徑下有png檔案wtclablogo.png
,則輸入
-
wsee wtclablogo.png
將顯示png圖片如下。
-
輸入絕對路徑或其他相對路徑也可得到相同結果。
-
輸入網址測試:
wsee -https://www.baidu.com/s?wd=CSDN%20C語言
將得到通過百度直接搜尋兩關鍵字的結果:
WSEE的功能還不只如此
WSEE還可以直接開啟以.txt
、.c
、.cpp
、.
h` 等為副檔名的文字或程式碼檔案。如:
wsee ../MainFrm.cpp
wsee ../Readme.txt
wsee ../MainFrm.h
現在的結果
對比設計要求,現在看哪些做到,還有哪些沒有做到:
- 能顯示各種格式的點陣圖圖片 (是一個看圖軟體)—做到了
- 能顯示向量圖(svg,wmf,emf) —做到了
- 能顯示動畫(gif)或flash的swf —做到了
- 能看各種格式的視訊 (是一個視訊播放器) —沒做到。
- 能播放音訊檔案 (是一個音訊播放器) —沒做到。
- 能閱讀pdf格式文件 (是一個Acrobat Reader)—做到了
- 這個軟體要是有原始碼的(自己編寫的) —做到了
- 無商業版權衝突的,可以帶上自己的LOGO。 —做到了
- 在軟體體積上不能太大,最好在1M以內。 —做到了(24K)
- 這個軟體是以命令列模式工作的。—做到了
- 而且編寫的程式碼量在100行以內。 —做到了(50行)
增強部分:
- 可訪問網際網路任意網址。並可帶引數,實現利用百度的關鍵詞檢索。
- 能查閱TXT文字及原始碼。