2011年12月15日 星期四

Crystal Report 9 以後適用的“拆解長字串成多行”函數

//
// 將長字串拆解成數行,中間用 CR+LF 分開
// Crystal Report 9 以後適用
//
StringVar s := {要拆解的欄位};                // 要拆解的字串
StringVar output := '';                     // 輸出字串
NumberVar CharsInALine := 20;               // 一行幾個字
NumberVar currLength := 0;
while Length(s) > 0 do
(
  // 這只是很粗略的判斷,假定使用者只會輸入半形英數字跟中文字,
  //
不會使用半形的特殊符號,如半形日文假名
  if AscW(s) > 256 then
  (   
    currLength := currLength + 2;           // 中文字,長度 + 2
  )
  else
  (
    currLength := currLength + 1;           // 文數字,長度 + 1
  );
  output := output + s[1];
  if currLength >= CharsInALine then
  (
    output := output + Chr(13) + Chr(10);
    currLength := 0;
  );
  s := Mid(s, 2);
);
output;

2011年10月9日 星期日

用 NPOI 在 Excel 工作表中畫斜線

程式碼如下:
using NPOI;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;

……

// 於工作表上建立 HSSFPatriarch,注意!一張工作表只可以建立一個 HSSFPatriarch
HSSFPatriarch p = sheet1.CreateDrawingPatriarch() as HSSFPatriarch;

// new HSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2) // 就是從 (col1, row1) 儲存格的 (dx1, dy1) 點 // 到 (col2, row2) 儲存格的 (dx2, dy2) 點建立一個繪圖物件的涵蓋範圍 HSSFClientAnchor a = new HSSFClientAnchor(0, 0, 0, 0, 0, 0, 1, 1); // 建立一個 HSSFSimpleShape 繪圖物件,範圍是 a,物件會充滿整個範圍 HSSFSimpleShape s = p.CreateSimpleShape(a); s.ShapeType = HSSFSimpleShape.OBJECT_TYPE_LINE; // 設定線條類型為線條 s.LineStyle = HSSFSimpleShape.LINESTYLE_SOLID; // 設定為實線 s.LineWidth = 1; // 限定線條寬度為 1

2011年9月15日 星期四

dbExpress 啟動交易時,出現「與異動管理員建立連線的要求遭到拒絶」訊息的 Trouble Shotting

前天收到同事傳來的一封郵件,裡面提到他有一個挑單畫面,挑單之前會先修改數量然後再挑單 (修改的數量不需要更新回資料庫)。挑單確定之後,根據挑選到的資料去異動另外一個資料表。可是,當異動另外一個資料表時,發生了「與異動管理員建立連線的要求遭到拒絶」的錯誤訊息。

原先我以為是 MSDTC 服務沒有啟動,請他確定是否有啟動,同事說已經啟動了仍然發生錯誤,接下來同事貼了他的程式碼,說是在啟動交易時發生的錯誤訊息。

於是我想到是不是因為挑單畫面的「修改數量」產生了擱置的異動,使得接下來的交易啟動時,因為有擱置的異動而無法啟動?

在說明如何修改之前,先說明一下挑單畫面的結構。
挑單畫面的組成很簡單,一個 PageControl,第一頁是挑單畫面,第二頁是查詢畫面。進入挑單時切到第一頁,可以預先傳入條件查詢出可供挑單的資料,也可以手動切換到第二頁自行查詢出供挑單的資料。查詢是使用 SQLQuery + DataSetProvider + ClientDataSet,以 TDBGrid 顯示資料。

我的想法是:如果能避免產生「擱置的異動」,就不會阻擋到接下來的交易了。

於是做了這樣的修改:

  1. 清除畫面上 ClientDataSet 的 ProviderName 屬性
  2. ClientDataSet.Open 之前,設定 ProviderName 屬性,讓 ClientDataSet 可以接到後面的資料來源,把資料收進來
  3. ClientDataSet.Open 之後,清除 ProviderName 屬性,使 ClientDataSet 做出的所有異動與後面的資料來源隔離開來

經過這樣的修改,這個問題就解決了。在此提供給大家做個參考。

2011年6月18日 星期六

改善 ASP.Net Menu 控制項點擊有效區域太小的問題

使用過 ASP.Net Menu 控制項的朋友都會發現這個問題:點擊有效區域 (也就是會變成手型游標的區域) 僅限於功能表的文字部份,但是 Hover 的效果卻及於功能表項目的全部。導致「雖然看到功能表項目變色了,但是點擊無效,必須游標變成手型才可以」,而讓使用者有不好的操作體驗。

如何解決這個問題?靠一點 css 的輔助就可以了。
將以下的 css 加入您的 css 檔

a.menu
{ display:block; width:100%; height:100%; padding-top:8px; } a.menu:hover { background-color: Gray; }

然後設定 Menu 控制項的 StaticMenuItemStyle 以及 DynamicMenuItemStyle 的 CssClass="menu"
a.menu 中的 padding-top:8px,以及 a.menu:hover 需要依照實際狀況做調整

這樣套用之後,功能表的點擊有效區域就可以括及功能表項目的全部範圍了

2011年6月6日 星期一

Delphi ListBox 顯示多欄文字

  1. 設定 ListBox.TabWidth,單位是 Dialog Base Unit (DBU),以定寬字來說,英數字寬是 4 DBU,中文字寬是 8 DBU,所以每一欄 20 個英數字寬度的話,TabWidth 就要設定為 80
    不用管一個 DBU 合多少 Pt,DBU 是相對單位,會跟著字的大小而變化的
  2. Items.Add 時,要分欄的地方,插入 Tab 字元,可以用 #9 或是 ^I 例如:
    Items.Add('0001'#9'這是品名');
    或是
    Items.Add('0001'^I'這是品名');
  3. 沒辦法各欄設定不同寬度,所以 TabWidth 請設定大一點,或是最長的欄放最後
    如果一定要各欄不同寬度顯示,請改用 TListView

2011年6月2日 星期四

Delphi + PostgreSQL 處理 bytea 欄位的注意事項

設定 PostgreSQL ODBC 時,要把圖中的「bytea as LO」選項勾起來,這樣使用 bytea 欄位型態就會被判別成 TBlobField,而不是 TVarBytesField

如此一來,就可以使用 TBlobField.LoadFromFile() 跟 SaveToFile() 來存入與讀取 bytea 欄位的內容了

若讀取時只想使用 TImage 顯示,不想存檔也可以 (以 JPG 圖檔為例子)
uses jpeg;     // 支援 JPEG 圖檔
var blob: TStream;

blob := ADODataSet1.CreateBlobStream(BlobField, bmRead);
try
  blob.Seek(0, soFromBeginning);
  Image1.Picture.Graphic := TJPEGImage.Create;
  Image1.Picture.Graphic.LoadFromStream(blob);
finally
  blob.Free
end; image

2011年5月12日 星期四

XMLHttpRequest 的應用:灌垃圾資料給釣魚網站

今天有一個許久未聯絡的同學忽然間丟MSN水球給我,第一時間的直覺就是詐騙,要買遊戲儲值卡的。果不其然,聊不到兩句就開始問我有沒有空,可不可以幫他買卡等等,我用幾個爛藉口推掉之後,他留下一個超連結就離線了。

點擊超連結,果然出現一個很像 Windows Live 登入的網頁,做得十分粗糙,連 Title 都沒有改,還是“Untitled Document”,唉~~要騙人帳號也搞像一點嘛!於是我就拿出了我之前寫的小程式,一個 html 檔案,填入了一些資料,開始向那個釣魚網站灌垃圾資料

這隻程式很簡單,就是使用 XMLHttpRequest 對釣魚網站 POST 假資料,假資料當然是使用亂數產生,主要的部份是這樣子的:

//產生一個XMLHttpRequest物件
function initRequest()
{
  var A=null;
  try
  {
    A = new ActiveXObject("Msxml2.XMLHTTP")
  }
  catch(e)
  {
    try
    {
      A = new ActiveXObject("Microsoft.XMLHTTP")
    }
    catch(oc)
    {
      A = null
    }
  }
  if (!A && typeof XMLHttpRequest != "undefined")
  {
    A = new XMLHttpRequest()
  }
  if (!A && window.createRequest)
  {
    try
    {
      A = window.createRequest();
    } catch (e)
    {
      A = null;
    }
  }
  return A
}
//取亂數帳號密碼,塞入釣魚網頁
function DoBurst()
{
  try
  {
    // 宣告變數
    username = "";
    password = "";
    // 取得輸入資料
    actionUrl = document.getElementById("actionUrl").value;
    usernameId = document.getElementById("usernameId").value;
    passwordId = document.getElementById("passwordId").value;
     // 取亂數拼湊假的帳號跟密碼
    c = Math.floor(Math.random() * 8) + 5;
    for (n=0; n < c; n++)
    {
      username += charSet.charAt(Math.floor(Math.random() * charSet.length));
    }
    username += document.getElementById("usernameSuffix").value;
    c = Math.floor(Math.random() * 8) + 5;
    for (n=0; n < c; n++)
    {
      password += charSet.charAt(Math.floor(Math.random() * charSet.length));
    }

    // submit
    url = actionUrl + "?" + usernameId + "=" + username + "&" + passwordId

+ "=" + password;

 

    if (typeof XmlHttp == "undefined")
    {
      XmlHttp = initRequest();
    }

 

    XmlHttp.open("POST", url, true);
    XmlHttp.onreadystatechange = ShowResult;
    XmlHttp.send("");
    // 計數器累加,並更新畫面
    i++;
    document.getElementById("sendTimes").innerText = i;
  }
  catch(e)
  {
  }
}

然後使用 interval 定時重複執行,就這樣簡單!

2011年3月9日 星期三

Ultra VNC 的最佳選項

1. 要搭配 Video Hook Driver
2. 「Check the Cideo Hook Driver」按鈕要連線時按才有意義image

2011年1月30日 星期日

Ubuntu Server 10.10 安裝 ASP.Net 網站伺服器的步驟

一、安裝 mono 以及 xsp

sudo apt-get install mono-gmcs
sudo apt-get install mono-xsp2
sudo apt-get install mono-apache-server2
sudo apt-get install libapache2-mod-mono
sudo a2enmod mod_mono

二、修改 /etc/apache2/mods-enabled/mod_mono.conf
成為以下這樣:
===== 從這裡開始 =====
AddType application/x-asp-net .aspx .ashx .asmx .ascx .asax .config .axd

DirectoryIndex index.aspx
DirectoryIndex Default.aspx
DirectoryIndex default.aspx

MonoAutoApplication enabled
MonoServerPath "/usr/bin/mod-mono-server2"

Include /etc/mono-server2/mono-server2-hosts.conf
===== 到這裡結束 =====

三、重新啟動 apache2
sudo /etc/init.d/apache2 restart

若要讓 Visual Studio 跟 MonoDevelop 共用網站專案的話
要使用「ASP.Net 應用程式」開發,不可以使用「ASP.Net 網站」開發
這樣平常就可以使用 Visual Studio 開發,要部署到 Ubuntu Server 時,再用 MonoDevelop 編譯一次就好