1. 程式人生 > >基於IE核心的多媒體檔案視覺化程式實現(二)

基於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.comwsee /w /www.abc.com也可)則順序彈出兩訊息框:
在這裡插入圖片描述

說明引數傳入與我們的想法一致。

接下來對傳輸的引數進行處理就可。

引數格式設計為:

  • 如無引數,則顯示幫助資訊。

  • 通過第1個引數傳遞檔名或網址,其他引數項直接丟棄。

    • 如果引數以減號-/號起頭,則認為是http網址,傳入後將首字元(減號或/號)去掉送Navigate2函式即可。
    • 如果引數以其他字元起頭,則認為是本地檔案。如檔案存在,則將其轉換這絕對路徑送Navigate2函式。
    • 對於本地檔案,判斷如是絕對路徑的,則直接送Navigate2函式。絕對路徑的標誌是:第2字元為冒號。如d:\\xxx\\yyy\\zzz.pngd:/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文字及原始碼。