程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> Visual Basic語言 >> VB綜合教程 >> VisualBasic軟件設計中的幾個問題

VisualBasic軟件設計中的幾個問題

編輯:VB綜合教程
在軟件開發過程中,有一些看似很簡單的問題,卻很容易被一般的開發人員所忽略,這些“Bugs”的存在,影響我們軟件走向商品化。下面所列出的是筆者在使用VisualBasic開發軟件時,碰到了幾個這類問題,這裡給出其解決方法,供大家探討交流。
  
  一防止應用程序加載兩份
  當我們的應用程序在Windows下運行後,在操作過程中,有時會把它最小化隱藏起來,或者切換到程序管理器下進行其它操作,而後又想進入原來的應用程序,這時如果忘記了剛才啟動的應用程序,又去重新啟動該應用程序,在內存中就同時加載了兩份同樣的應用程序,這樣不但占用了內存空間,而且容易引起誤操作,造成數據的損失。為了避免這種情況發生,就需要程序能夠給出提示“已經加載過”或直接進入第一次被加載的應用程序中。對於這個問題,看起來比較難辦,其實我們只要對Windows管理應用程序的機理有所了解,就很容易解決。
  我們知道,對於每一個運行著的應用程序,Windows都分配給一個唯一的“句柄(Handle)”和一個模塊代碼(Module)。當同時運行兩份相同的程序時,兩份程序的模塊代碼都相同,因此,只要找到內存中兩個相同的模塊代碼,我們就知道有兩份程序在運行,從而可以控制它。Windows提供的兩個接口函數GetModuleHandle和GetModuleUsage可以完成此任務。具體方法如下,首先在一個新的模塊文件(*.Bas)中聲明API函數。
  
  DeclareFunctionGetModuleHandleLib"Kernel"(ByVallpProgName$)
  
  DeclareFunctionGetModuleUsageLib"Kernel"(ByValhModule)
  
  同時建立一個子過程,名字為main,子過程中的代碼如下:
  
  SubMain()
  OnErrorGoToerrMain‘錯誤處理
  DimhModule‘模塊句柄
  DimAppCount‘應用程序的個數
  appPath$=app.Path ""‘應用程序的啟動路徑
  hModule=GetModuleHandle(appPath$ app.EXEName ".exe")‘獲得該程序的句柄。
  AppCount=GetModuleUsage(hModule)‘獲得模塊代碼,即運行的應用程序數目。
  lfAppCount>1Then‘同一應用程序數大於1
  MsgBox"程序已經加載",64
  End‘結束當前啟動的應用程序
  Elsc
  mainForm.Show‘mainForm是程序的主窗體
  Endlf
  ExitSub
  errMain:
  lfErr<>0Then
  MsgBox"啟動程序時發生錯誤",64
  ExitSub
  Endlf
  EndSub
  該過程完成後,在VB3.0主菜單[options]下,選擇[Project]菜單項,設定[StartupFrom]項為Submain,即程序運行時,最先從Submain子程序開始。這樣保證上面的代碼一定被執行。Submain是VB3.0約定的子過程名,不能用其它的名字來代替。
  重新生成EXE文件,在程序管理器下,啟動該應用程序,然後把產生的窗體最小化,接著從程序管理器下再運行它,用戶將看到一個消息框,告訴用戶,應用程序已被加載過了,第二份程序終止執行。上面的程序僅用來防止加載二份程序,但還沒有做到當不能啟動第二份時,自動進入到第一份程序。要做到這一點,所涉及的程序較復雜,這裡就不詳細介紹了。
  
  二判斷Windows的安裝路徑
  在我們開發的軟件中,有時會直接調用Windows提供的小應用程序,如計算器、計事本等;或需要把一些特殊的文件放到Windows或SYSTEM的路徑下。通常,Windows都安裝在C:\WINDOWS目錄下,但用戶可以任意修改Windows的主目錄名,因此,在我們的軟件中,就需要判斷Windows的安裝路徑。對於這個問題,Windows提供了兩個API函數:GetWindowsDirectory和GetSystemDirectory,可以返回Windows目錄和SYSTEM目錄的名稱。
  為此,編制一個通用函數GetWinDir,它返回Windows的安裝目錄名稱。類似,可以寫出GetSysDir,略。
  
  在*.BAS模塊文件中聲明API函數
  
  DeclareFunctionGetWindowsDirectoryLib"Kernel"(ByValIpBufferAsString,ByValnSizeAsInteger)asIntegerFunctionGetWinDir()AsStringDimWindir$Windir$=Space$(144)‘144是WINDOWS目錄名稱理論上的最大長度。
  
  lfGetWindowsDirectory(Windir$,144)=0Then
  MsgBox"不能確定WINDOWS的安裝路徑",16
  GetWinDir=""
  Else
  Windir$=ALLTrim$(Windir$)
  ifRight$(Windir$,1)<>“”thenWindir$=Windir$ “”
  ‘加上反斜槓
  GetWinDir=Windir$
  Endlf
  EndFunction
  其中ALLTRIM是用來去掉字符串中空字符的函數
  FunctionALLTrim(FatStr$)AsString
  'thisFunctiondeleteSpacecharinstringofFatStr$
  DimSlimStr$,I
  SlimStr$=FatStr$
  I=lnStr(SlimStr$,Chr$(0))‘空格的位置
  IfIThenSlimStr$=Left$(SlimStr$,I-1)
  SlimStr$=Ltrim$(Rtrim$)(SlimStr$))
  AIITrim$=SlimStr$
  EndFunction
  三在關掉窗體前提示保存數據
  一般說來,通常用5種方式可以關閉一個應用程序:
  1.用戶選擇了當前窗體ControlBox中的[關閉]命令
  2.激發程序中的結束命令代碼(如End,Unload)
  3.退出Windows
  4.在Windows的任務列表中關閉應用程序。
  5.多文檔操作時,關閉主MDI窗體,引起子MDI窗體關閉。
  在關閉一個應用程序前,我們要給用戶一個機會,提示“是否保存數據”,或者取消“關閉”的操作。在VB中,窗體的關閉引發的是Form_Unload事件,我們可以對該事件進行編程,來控制“關閉”操作。假設現已有一個過程FileSave用來保存文件,則可以這樣來編寫程序。
  SubForm_Unload(CancelAslnteger)
  selectcastMsagbox(“是否保存數據?”,3 32)
  ‘Yes,No,Cnacel三種選擇
  case6‘YES
  FileSave‘保存數據
  case2‘cancel
  Cancel=TRUE‘取消關閉操作
  caseelse‘NO‘不保存,執行關閉操作
  Endselect
  EndSub
  上面代碼中的Cancel變量,是Form_unload事件本身的固有傳出變量,它給Windows控制過程傳遞消息,從而控制程序的走向。
  
  上面三個例子,只是軟件完善過程中的一些小問題,要使軟件穩定可靠,需要做大量細致認真的工作。有些問題,我們可以通過發掘VB本身的潛力,深入掌握一些過程的操作技巧來解決;而有些較復雜的問題,涉及到Windows底層方面的操作,采用Windows的API函數,可以很容易實現。當然這需要對Windows的函數和機理有一定的了解。隨著Windows編程水平的提高,我們會逐漸學會並喜歡利用API函數來輔助完成程序編碼。->

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved