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日 星期三

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 編譯一次就好