開發Windows Mobile今日插件 -- 內存電量,桌面便箋,桌面記單詞

本篇文章講解的是開發 Windows Mobile 上的今日插件。關于是今日插件,在 PPC 或者 SP SDK 的幫助文檔中有相關的章節介紹,在網絡上也有一些帖子和資源講解。在這里簡要回顧一下。今日插件就是在windows mobile的桌面上顯示的條目,例如系統提供的“日歷”(Calendar),主人信息,以及許多第三方開發的今日插件等等。由于桌面是開機后的第一個屏幕,所以插件顯示在屏幕上將會得到用戶最多的瀏覽時間。這里我們主要講解的是用戶自定義插件的開發。自定義插件如下圖所示:

??????

一個插件就是一個位于屏幕上的窗口,每個插件負責自己的繪制和對用戶輸入的響應。插件可以通過給自己的父窗口(桌面窗口)發送TODAYM_DRAWWATERMARK 消息,委托父窗口為自己繪制背景,也就是通過把自己的HDC傳遞給shell來完成的,這樣插件就看起來好像是“透明”的效果。同時,shell 也負責在相鄰的插件之間繪制一條分割線。
通常,PPC 最多允許加載 12 個插件。最大插件數量是由 K_cTodayItemsMax 定義的。
對于自定義的插件,要求開發者提供一個DLL函數并注冊到注冊表: HKLM\Softeware\Microsoft\Today\Items;
如下圖,我們使用遠程注冊表查看工具打開一個插件的在注冊表中的位置:

??????

在下面包含了所有今日插件的鍵。每個插件將含有下列的值:?

◆Type (DWORD);
對自定義插件來說,等于4。它是 SDK 中的插件類型枚舉中的一個值( tlitCustom)。?
typedef enum _TODAYLISTITEMTYPE {?
tlitOwnerInfo = 0,?
tlitAppointments,?
tlitMail,
tlitTasks,
tlitCustom, //自定義插件 = 4
tlitNil
} TODAYLISTITEMTYPE;

◆Enabled;
插件是否啟用。用戶能夠在設置-今日-項目中進行啟用或禁用。

◆Options;
是否含有設置對話框。也就是設置-今日-項目中插件被選中時的 “選項按鈕” 的 Enabled 狀態。

◆DLL:
插件dll的路徑。

◆Selectability;
可選項,插件是否可以被選中(用戶在屏幕上按導航鍵時)。通常為1,表示允許被選中。當允許選中時,用戶按上下方向鍵,被選中的插件背景會高亮。如果不能選中,就會跳過該插件。

◆Order;
可選項,插件顯示循序的排序值。缺省時由系統自動設置。

下面我們再介紹插件的協議,也就是插件的DLL應當滿足以下要求。

(1)要求 dll 導出序號為 240 的以下函數,以初始化和創建插件窗口;
??????#define ORDINAL_INITIALIZEITEM????? 240
typedef HWND (*PFNCUSTOMINITIALIZEITEM)(TODAYLISTITEM *, HWND);
參數1:TODAYLISTITEM 結構的指針,包含了該插件在系統中注冊的相關信息。
參數2:桌面窗口的句柄,它將成為插件窗口的父窗口。

(2)如果插件具有設置對話框,則要求dll導出序號為 241 的以下函數,作為設置對話框的窗口過程;
??????#define ORDINAL_OPTIONSDIALOGPROC?? 241
typedef BOOL (*PFNCUSTOMOPTIONSDLGPROC)(HWND, UINT, UINT, LONG);
同時要求dll 提供資源ID為 500的一個對話框資源作為設置對話框的模板。(可以通過手工修改 resource.h 中的定義)

(3)shell 將向插件窗口發送以下信息,要求插件處理這些消息;
??????WM_TODAYCUSTOM_CLEARCACHE
告知插件正在被從顯示中卸載,要求插件清理自己所維護的數據緩存。

??????WM_TODAYCUSTOM_QUERYREFRESHCACHE
此消息在桌面顯示期間以每2秒鐘一次的頻率周期性對所有插件發送。詢問插件是否需要進行更新。
在插件首次加載時,還要求插件告知系統插件的高度以對插件窗口進行布局。由于插件窗口被上下垂直分布,所以寬度對于系統屬于已知的。如果返回TRUE,表示要求進行更新。如果不需要更新返回FALSE。

(4)同時插件還能夠向父窗口發送以下消息,以輔助繪制。
??????TODAYM_GETCOLOR
詢問系統當前使用的前景色,背景色,高亮前景色等信息。以便繪制時,和系統使用的主題風格保持一致。

??????TODAYM_DRAWWATERMARK
要求shell 為插件繪制背景。也就是把背景位圖復制到插件窗口的背景。

好了,關于插件開發規則我們就簡要介紹到此。在開發插件時,開發者的主要任務是編寫插件窗口\設置對話框的窗口過程,完成屬于自己的功能。這里要求具有的是windows開發的一些基礎。我們不細作介紹了。下面是我在這幾天制作的插件。

(1)根據 SDK 中 范例改編而成的 memWatcher 插件 和 “桌面便箋”。效果如下:

??????

在左圖是SDK中的 memWatcher 范例在模擬器中的顯示效果,右圖是經過我適當改寫后,在實際HTC S1中運行的效果。SDK范例顯示了程序和存儲的百分比,并且創建了兩個進度條窗口顯示。經過我的改寫,我把進度條去掉了,從而可以把信息壓縮到一行以內,這樣可以節省屏幕空間,并且增加了電池電量的顯示。
獲取這些信息的相關API函數是:
??????GlobalMemoryStatus,GetStoreInformation,GetSystemPowerStatusEx;

下面我們看下桌面便箋插件,這個插件發布在 pdafans 論壇后,很快就有網友向我反饋了備忘錄的內容在重啟后消失,這是因為我做的這個插件也僅僅是個范例來使用,測試了我的想法是可行的,所以并沒有考慮那么多。便箋的內容被放到了內存里,聲明周期和DLL一樣,這也一旦DLL被卸載,存儲在內存中的內容也就失去了。這也提醒了我們一點,我們的插件應該將數據持久化。所以我又修改了這個插件,把備忘信息和圖標索引存儲到了注冊表中,也就是插件注冊的鍵下面新增了兩個值。這樣我們就可以保證每次插件啟動時都會從注冊表中讀取出上次的用戶記錄的內容。
當用鼠標點擊桌面便箋時,就會彈出一個對話框用于設置新的備忘內容,如下圖所示:

??????

這個對話框中具有一點難度和技巧性的是上面的圖標選擇反饋,全部是通過鼠標點擊事件來完成的。我們在對話框的 WM_ONPAINT 消息處理中,在對話框上繪制了所有可選圖標,每個圖標實際上是16*16像素大小,所以我指定的網格是20*20像素,在每個網格中繪制一個圖標,并對被選中圖標繪制了一個藍色矩形框表示選中狀態。當鼠標點擊到其他圖標時,我們就要更新這個藍色矩形。同時我們也要根據鼠標位置在網格中正確的定位要當前位置選中的鼠標索引。這里的處理并不算非常難,但是需要少許的耐心。
顯示和隱藏輸入面板,在 .NET CF中,有一個inputPanel控件,我們 可以方便的設置它的Visible屬性去控制。而在EVC中,我們是通過下面的API函數去顯示或者隱藏SIP的。
??????SipShowIM(SIPF_ON) 和 SipShowIM(SIPF_OFF);
或者我們也可以使用:SHSipPreference(hDlg, SIP_UP) ,去要求 Shell 浮出輸入面板。

(2)桌面記單詞插件。
桌面記單詞插件的靈感是來自桌面上的類似工具,即有一個頂層窗口,以一個固定的頻率切換詞條顯示,以幫助用戶背單詞。我這里就是模擬這種軟件的效果做的一個今日插件。當然它不僅僅可以背單詞,也可以顯示其他字典內容,例如唐詩宋詞,名言名句等等。用戶可以自定義字典文件,本質上就是一個文本文件,并通過修改配置文件把字典添加進來。

為了降低讀文件的頻率,我在插件內維護了一個詞條緩存(緩存10個詞條),每次一次性嘗試從文件中加載10個詞條文件(每個詞條也就是文本文件中的一行)到內存中。當詞條正在滾動期間,文件保持打開狀態。當暫停滾動時,將會關閉文件。插件利用每2秒鐘接收到的消息去滾動詞條。效果如下圖所示:

??????

開發這個插件時,我忽然發現 Pocket PC 的操作系統是不支持讀寫 ini 文件的相關API函數的。我去網絡上找了下相關代碼,但是沒有看到特別滿意的。因此我自己用C語言寫了幾個和API函數功能相同的讀 ini 文件的函數。函數命名也是完全相同的,為了在 PC上進行測試,我在每個函數名前面加了 Ce ,以和系統的API函數區分開。我這里僅僅為了插件功能寫了有限的幾個函數,這里以 CeGetPrivateProfileString 為例給出代碼。
在PC上,這個函數負責讀取 ini 文件某個 section 中某個 key 的值。為了同時在 unicode 和 多字節字符串環境中適用,我又把相關的文件和字符串操作函數進行了宏定義,并且以這種方式命名:?
??????t_多字節版本函數名
這是因為對多字節版本的函數我們通常更加熟悉它的命名。例如對于 t_strcpy 等等。下面是這個函數的代碼:

ContractedBlock.gifExpandedBlockStart.gifCode_CeGetPrivateProfileString
#ifdef??UNICODE???//?r_winnt

????
#define?t_fopen?????????_wfopen
????
#define?t_fgets????????????fgetws
????
#define?t_sprintf????????swprintf????//格式化文本
????
#define?t_strcpy????????wcscpy
????
#define?t_strncpy????????wcsncpy????????//拷貝指定個數的字符
????
#define?t_strcat????????wcscat????????//append?a?string
????
#define?t_strtol????????wcstol
????
#define?t_strlen????????wcslen
????
#define?t_strcmp????????wcscmp
????
#define?t_stricmp????????_wcsicmp????//忽略大小寫的字符串比較
????
#define?t_strncmp????????wcsncmp????????//比較n個字符
????
#define?t_strchr????????wcschr????????//find?a?character?in?a?string
????
#define?t_strrchr????????wcsrchr????????//從結尾向前查找字符

#else??//ASCII?CODE

????
#define?t_fopen?????????fopen
????
#define?t_fgets????????????fgets????????//讀取一行文本
????
#define?t_sprintf????????sprintf????????//格式化文本
????
#define?t_strcpy????????strcpy
????
#define?t_strncpy????????strncpy????????//拷貝指定個數的字符
????
#define?t_strcat????????strcat????????//append?a?string
????
#define?t_strtol????????strtol????????//把字符串轉換成long(int32)
????
#define?t_strlen????????strlen
????
#define?t_strcmp????????strcmp????????//比較字符串
????
#define?t_stricmp????????_stricmp????//忽略大小寫的字符串比較
????
#define?t_strncmp????????strncmp????????//比較n個字符
????
#define?t_strchr????????strchr????????//查找字符
????
#define?t_strrchr????????strrchr????????//從結尾向前查找字符

#endif

#define?LINESIZE????260????//行緩沖區大小


//從appname(section)中讀取string類型key
DWORD?CeGetPrivateProfileString(
????LPCTSTR?lpAppName,????????????????
//section?name:?[lpAppName]
????LPCTSTR?lpKeyName,????????????????//lpKeyName=lpReturnedString
????LPCTSTR?lpDefault,????????????????//未找到時的默認值
????LPTSTR?lpReturnedString,????//[out]?查找到的結果
????DWORD?nSize,????????????????????????????//[in]lpReturnedString的字符數,注意單位不是字節!
????LPCTSTR?lpFileName
????)
{
????DWORD?ret?
=?0;
????FILE?
*stream;
????
bool?bFindVal?=?false;
????
bool?bFindSection?=?false;
????TCHAR?line[?LINESIZE?];
????size_t?sectionLength,?keyLength,?lineLength;
????
????stream?
=?t_fopen(lpFileName,?_T("r"));
????
if(stream?==?NULL)
????{
????????
//設置默認值
????????t_strcpy(lpReturnedString,?lpDefault);
????????ret?
=?t_strlen(lpReturnedString);?
????????
return?ret;
????}
????
????sectionLength?
=?t_strlen(lpAppName);
????
????
while(t_fgets(line,?LINESIZE,?stream)?!=?NULL)
????{
????????
//忽略注釋行和空行
????????if(line[0]?==?0?||?line[0]?==?';')?continue;
????????lineLength?
=?t_strlen(line);
????????
//注意:把LF(0xa)字符替換成0,這在UNICODE環境下可能出現結尾是LF)
????????if(line[?lineLength?-?1?]?==?0x0a)
????????{
????????????line[?lineLength?
-?1?]?=?0;
????????????lineLength
--;
????????????
//注意此時可能會成為空字符串
????????????if(lineLength?==?0)?continue;
????????}
????????
????????
//嘗試尋找到?section
????????if(!bFindSection)
????????{
????????????
if(line[0]?!=?'[')?continue;?//本行是否是?[section]
????????????
//這里是我們想要的Section嗎?
????????????
//檢查這一行的寬度是否正好是section長度加2,?[lpAppName]
????????????if(line[sectionLength?+?1]?!=?']')?continue;
????????????
if(t_strncmp(line+1,?lpAppName,?sectionLength)?!=?0)?continue;
????????????
//Now?Section?will?appear?on?next?line?
????????????
//讀取section前求出?Key?的長度
????????????keyLength?=?t_strlen(lpKeyName);
????????????bFindSection?
=?true;????????????
????????????
continue;
????????}
????????
????????
//查找Key,?Section?End?
????????if(line[0]=='[')?break;?//遇到了下一個
????????????
????????
if(lineLength?<?keyLength+1?||?line[keyLength]?!=?'=')?continue;?//"KeyName="
????????if(t_strncmp(line,?lpKeyName,?keyLength)!=0)?continue;
????????
//Now?We?Get?the?Key!?
????????t_strcpy(lpReturnedString,?line?+?keyLength?+?1);
????????
//Now?It's?done.
????????bFindVal?=?true;
????????
break;
????}
????
????fclose(stream);
????
if(!bFindVal)
????{
????????
//設置默認值
????????t_strcpy(lpReturnedString,?lpDefault);?
????}
????ret?
=?t_strlen(lpReturnedString);?
????
return?ret;
}

下面是我提供了一個演示程序,由于我們知道了插件的協議,所以我們也可以顯示出其他插件的選項對話框,為了更具可讀性,代碼經過了精簡。

ContractedBlock.gifExpandedBlockStart.gifCode_顯示其他插件的選項對話框
TCHAR?path[256];
GetDlgItemText(hDlg,?IDC_DLLPATH,?path,?
256);
//?load?dll
g_PluginModule?=?LoadLibrary(path);
//?get?dlgproc?address 窗口過程函數的導出序號是241
g_PluginProc?=?(DLGPROC)GetProcAddress(g_PluginModule,?(LPCTSTR)241);
//?create?options?dlg
g_PluginDlg?=?CreateDialog(g_PluginModule,?(LPCTSTR)MAKEINTRESOURCE(500),?NULL,?g_PluginProc);
ShowWindow(g_PluginDlg,?SW_SHOW);
SetWindowPos(g_PluginDlg,?NULL,?
30,?80,?0,?0,?SWP_NOSIZE);
return?TRUE;

運行效果如圖所示:



最后我們開發好插件以后,可以利用SDK提供的打包工具,把插件制作成 cab 包,這樣復制到設備上即可自動安裝。打包是使用SDK提供的工具完成,但是我們首先需要自己為我們的軟件編寫一個 inf 文件,描述軟件的發裝過程。inf文件詳細描述了需要拷貝的文件清單,源目錄,目標目錄,要添加的注冊表信息等內容。這里可以參考 SDK中的范例,細節就不再描述了。這里我使用 mymemo 的 inf 文件做一個例子說明:為了更具可讀性,文件內容經過了精簡。

ContractedBlock.gifExpandedBlockStart.gifmymemo.inf
[Version]
Signature???
=?"$Windows?NT$"
Provider????
=?"Microsoft"
CESignature?
=?"$Windows?CE$"

[CEStrings]
AppName?????
=?"MyMemo"
InstallDir??
=?%CE2%?????????????;?"\Windows"?

[CEDevice]
UnsupportedPlatforms????
=?"HPC","Jupiter","Palm?PC2"
VersionMin?????????
=?3.0
VersionMax????????
=?6.0

[PPC2003_Device]
ProcessorType???????????
=?2577??????;?ARM?CPU

[SourceDisksNames.PPC2003_Device]
1?=?,"ARM?Files",,ARMV4Rel

[SourceDisksFiles]
"mymemo.dll"????????????????????=?1?????;?the?Today?plugin?dll

[DestinationDirs]
Files.Windows???????
=?0,%CE2%???????????;?"\Windows"?directory

[Files.Windows]
"mymemo.dll","mymemo.dll",,0x00000001

[Reg.Version1]
HKLM,Software
\Microsoft\Today\Items\%AppName%,Enabled,0x00010001,0
HKLM,Software
\Microsoft\Today\Items\%AppName%,Type,0x00010001,4
HKLM,Software
\Microsoft\Today\Items\%AppName%,Options,0x00010001,0
HKLM,Software\Microsoft\Today\Items\%AppName%,Selectability,0x00010001,1
HKLM,Software\Microsoft\Today\Items\%AppName%,IconIndex,0x00010001,0
HKLM,Software\Microsoft\Today\Items\%AppName%,DLL,0x00000002,"%InstallDir%\mymemo.dll"
HKLM,Software\Microsoft\Today\Items\%AppName%,Memo,0x00000002,"Type?here?to?input?memo"

打包工具是一個命令行程序,我們執行以下命令:
cabwiz mymemo.inf? /err errinfo.txt? /cpu PPC2003_Device

??????其中,/err選項指定錯誤輸出文件,當打包失敗時,這是診斷問題的重要信息。
/cpu選項指定是inf文件中定義過的CPU類型,如果在inf文件中定義了多種CPU類型,可以同時為多種CPU打包,所以一個inf文件可以多用。

最后我們給出相關的下載連接:
(1)程序存儲電量百分比顯示和桌面便箋插件的CAB包下載鏈接:
??????http://files.cnblogs.com/hoodlum1980/PPCCAB_MyMemo_MemWatcher.rar
(2)桌面記單詞插件的CAB包下載鏈接:
??????http://files.cnblogs.com/hoodlum1980/Recite_CAB_ARMV4.rar
(3)然后在給出一個我以前寫的C語言的俄羅斯方塊(最早發表在編程論壇),移植到PPC上的版本:
??????http://files.cnblogs.com/hoodlum1980/Tetris.rar
運行效果截圖:

??????

(4)最后我們給出本文提及所有源代碼的合集下載連接,全部使用EVC4.0使用C++開發。每個插件包含了用于打包的 inf 文件。
??????http://files.cnblogs.com/hoodlum1980/TodayPlugins.rar

轉載于:https://www.cnblogs.com/hoodlum1980/archive/2009/08/01/1536246.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379600.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379600.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379600.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c語言中將函數指針作為形參_在C中將有效指針作為NULL指針

c語言中將函數指針作為形參Prerequisite: An Example of Null pointer in C 先決條件&#xff1a; C中的空指針示例 Any pointer that contains a valid memory address can be made as a NULL pointer by assigning 0. 通過分配0&#xff0c;可以將包含有效內存地址的任何指…

[轉]一個清華計算機博士生的退學申請

偶然間在網上看到這篇帖子&#xff0c;回想起自己的求學經歷&#xff0c;思索良久。。。 本想找到原帖及作者&#xff0c;但是幾經搜索&#xff0c;發現原帖出自科學網&#xff0c;已被刪除。對此&#xff0c;我還能說啥&#xff1f;&#xff01; http://www.sciencenet.cn/m/u…

算法---遞歸

遞歸結題三部曲 何為遞歸&#xff1f;程序反復調用自身即是遞歸。 我自己在剛開始解決遞歸問題的時候&#xff0c;總是會去糾結這一層函數做了什么&#xff0c;它調用自身后的下一層函數又做了什么…然后就會覺得實現一個遞歸解法十分復雜&#xff0c;根本就無從下手。 相信…

給定條件找最小值c語言程序_根據給定條件最小化n的最小步驟

給定條件找最小值c語言程序Problem statement: 問題陳述&#xff1a; Given a number n, count minimum steps to minimize it to 1 performing the following operations: 給定數字n &#xff0c;執行以下操作&#xff0c;計算最少的步驟以將其最小化為1&#xff1a; Operat…

提高C#編程水平不可不讀的50個要訣

提高C#編程水平的50個要點 1.總是用屬性 (Property) 來代替可訪問的數據成員 2.在 readonly 和 const 之間&#xff0c;優先使用 readonly 3.在 as 和 強制類型轉換之間&#xff0c;優先使用 as 操作符 4.使用條件屬性 (Conditional Attributes) 來代替條件編譯語句 #if 5.總是…

那個年代的蘇聯歌曲

小時候&#xff0c;不時聽父親提起電影《這里的黎明靜悄悄》&#xff0c;怎么也想不到如此美麗的名字為什么要和戰爭聯系起來。后來在大學看了這部電影之后&#xff0c;開始認為這名字是合適的&#xff0c;因為電影講的是女性——戰場中的女性&#xff0c;各自都懷揣著愛情去保…

linux系統編程---進程總結

進程控制總結1 進程創建的三種方式forkvfrokclone2 進程終止進程正常退出returnexit_exit進程異常退出進程收到某個信號&#xff0c;而該信號使進程終止abort3 進程等待進程等待的方法waitwaitpid4 進程替換替換原理替換函數制作一個簡單的shell1 進程創建的三種方式 參考文章…

銀行賬務轉賬系統(事務處理)

流程如下&#xff1a; 創建項目工程如下&#xff1a; transfer包下的代碼如下&#xff1a; package beyond.transfer.dao;import java.sql.Connection; import java.sql.SQLException;import org.apache.commons.dbutils.QueryRunner;import beyond.utils.DataSourceUtils;pu…

【msdn wpf forum翻譯】TextBox中文本 中對齊 的方法

原文鏈接&#xff1a;http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/49864e35-1dbf-4292-a361-93f1a8400558問題&#xff1a;TextBox中文本中對齊&#xff0c;使用 TextBox.HorizontalContentAlignment"Center"行不通&#xff08;TextBox.VerticalConte…

wifi操作及實例

1.什么事WIFI 利用無線路由器上網的協議2.獲取WIFI網卡的狀態 WIFI網卡的狀態是由一系列的整形常量來表示的 有狀態&#xff1a; 網卡不可用WIFI_STATE_DISABLED 對應值為1 網卡正在關閉WIFI_STATE_DISABLING 對應值為0 網卡可用WIFI_STATE_ENABLED 對應的值為3 …

c語言 函數的參數傳遞示例_C語言中帶有示例的remove()函數

c語言 函數的參數傳遞示例C語言中的remove()函數 (remove() function in C) The remove() function is defined in the <stdio.h> header file. remove()函數在<stdio.h>頭文件中定義。 Prototype: 原型&#xff1a; int remove(const char* filename);Parameter…

使用ThreadLocal綁定連接資源(事務)

dao層代碼如下&#xff1a; package beyond.transfer.dao;import java.sql.Connection; import java.sql.SQLException;import org.apache.commons.dbutils.QueryRunner;import beyond.utils.DataSourceUtils; import beyond.utils.MyDataSourceUtils;public class TransferDa…

算法---棧和隊列

棧和隊列1 棧棧的順序存儲棧的鏈式存儲2 隊列隊列的順序存儲隊列的鏈式存儲3 棧和隊列的應用用棧實現隊列用隊列實現棧最小棧1 棧 參考文章&#xff1a; https://zhuanlan.zhihu.com/p/346164833 https://zhuanlan.zhihu.com/p/120965372#:~:text%E6%A0%88%E6%98%AF%E4%B8%80%…

學習網站LIST

面向對象的腳本語言Rubyhttp://rubycn.ce-lab.net/20020101.htmlRUBY文檔中心http://www.moer.net/ruby/doc/TCL腳本http://www.tclchina.com/Python快速入門http://wiki.woodpecker.org.cn/moin/WeiZhong/2006-01-17Python 研究(Dive Into Python)http://www.woodpecker.org.c…

再次參加(第七屆)商學院徒步戈壁挑戰賽,賦詞幾首

2012年5月21-25日&#xff0c;再次踏上甘肅莫賀延磧戈壁&#xff0c;參加第七屆商學院徒步戈壁挑戰賽。時隔五年&#xff0c;時空轉換。 少年游 ——戈壁緣 江南物華&#xff0c;遠水碧山&#xff0c;燈火相掩映。暮宴朝歡&#xff0c;酒綠燈紅&#xff0c;躑躅夜歸人。 孤城落…

Java StackTraceElement toString()方法與示例

StackTraceElement類的toString()方法 (StackTraceElement Class toString() method) toString() method is available in java.lang package. toString()方法在java.lang包中可用。 toString() method is used to represent stack trace element as a string or in other word…

增刪改查

web層代碼如下&#xff1a; package beyondwsq.web;import java.io.IOException; import java.sql.SQLException; import java.util.List;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; imp…

在WebBrowser中通過模擬鍵盤鼠標操控網頁中的文件上傳控件

引言 這兩天沉迷了Google SketchUp&#xff0c;剛剛玩夠&#xff0c;一時興起&#xff0c;研究了一下WebBrowser。 我在《WebBrowser控件使用技巧分享》一文中曾談到過“我現在可以通過WebBrowser實現對各種Html元素的操控&#xff0c;唯獨無法控制Html的上傳控件”&#xff0c…

編寫最簡單的字符設備驅動

編寫最簡單的字符設備驅動1 編寫驅動代碼2 編寫makefile3 編譯和加載驅動4 編寫應用程序測試驅動參考文章&#xff1a; linux驅動開發第1講&#xff1a;帶你編寫一個最簡單的字符設備驅動 linux驅動開發第2講&#xff1a;應用層的write如何調用到驅動中的write 1 編寫驅動代碼…

Java ObjectStreamField toString()方法與示例

ObjectStreamField類toString()方法 (ObjectStreamField Class toString() method) toString() method is available in java.io package. toString()方法在java.io包中可用。 toString() method is used to return a string that defines this field. toString()方法用于返回定…