bestlong 怕失憶筆記

當健忘逐漸成為一種隨機常態時,作筆記是非常必要的

Entries Tagged ‘Delphi’

在 Delphi 中獲得 GUID

GUID (Globally Unique IDentifier) 是一個 128-bit Integer (16 bytes) 的數值。

在 Delphi IDE 中可以按下 Ctrl + Shift + G 快捷鍵會出現類似下列的 GUID 值:

1
['{2F45BDFE-1BE4-404D-9C5B-4B481D6A7482}']

每次按下快捷鍵都會產生不同的 GUID 值。

而程式中產生 GUID 值的方式如下列程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TForm1.FormCreate(Sender: TObject);
var
  s_GUID: string;
  t_GUID: TGUID;
begin
  if CoCreateGUID(t_GUID) = S_OK then
  begin
    s_GUID := GUIDToString(t_GUID);
    ShowMessage(s_GUID);
  end else begin
    ShowMessage('Create GUID ERROR.');
  end;
end;

In Delphi 5 need uses ComObj, ActiveX.

也可以當作 UUID 來應用。

Comments (1)

開發Delphi資料庫程式時不建議使用函數InsertRecord與AppendRecord

InsertRecord() 與 AppendRecord() 是 Delphi 的資料插入與新增的函數。雖然這兩個功能可以簡易方便的使用,若是在程式中大量使用,最後將會面臨欄位對應的問題。

為什麼呢?

當有需要調整DataSet元件中的欄位順序(我想應該會常常發生)或資料庫欄位的順序的時候,你就需要同步修改這兩個函數的資料順序,所以用的範圍越多問題越大。連調整欄位順序都有影響就是高度耦合的問題。

接手的舊系統就是有一堆這樣的狀況,只好先作苦力將全部程式碼都轉換過,再開始動資料庫。

Leave a Comment

Delphi 碰到 DesignIntf.dcu not found

若是要將由 Delphi 5 開發元件移轉到Delphi 6 或 7 大概都會碰到這個問題。

若只是程式當然可以將全部的 uses 替換成新的就好。但是若是自行開發的元件可就需要同時支援多個版本,總不能一個版本維護一套程式碼。只要利用 Compiler 的指令來加強一下就可以解決問題了:

1
2
3
4
5
6
7
8
9
10
11
{$UNDEF DEL345}
{$IFDEF VER100} {$DEFINE DEL345} {$ENDIF}
{$IFDEF VER120} {$DEFINE DEL345} {$ENDIF}
{$IFDEF VER130} {$DEFINE DEL345} {$ENDIF}

uses
{$IFDEF DEL345}
DsgnIntf
{$ELSE}
DesignIntf, DesignEditors, VCLEditors, RTLConsts
{$ENDIF};

參考資料:

http://www.chillibear.org/blog1.php/delphi/

http://www.mustangpeak.net/ota_publishedprop_forms.htm

Leave a Comment

Delphi 的 ExtractFileDir 與 ExtractFilePath 函數有何差異?

ExtractFileDir() 與 ExtractFilePath() 是有差異的,直接用程式來看差異結果

1
2
3
4
5
6
7
8
procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Clear;
  Memo1.Lines.Add(ExtractFileDir('C:\a.exe'));
  Memo1.Lines.Add(ExtractFilePath('C:\a.exe'));
  Memo1.Lines.Add(ExtractFileDir('C:\Program Files\a.exe'));
  Memo1.Lines.Add(ExtractFilePath('C:\Program Files\a.exe'));
end;

得到的執行結果是
C:\
C:\
C:\Program Files
C:\Program Files\

得知 ExtractFilePath() 的結果都會在路徑後保留 \

Leave a Comment

控制 Windows 音效管理員作靜音切換

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
uses
  MMSystem;

function GetMasterMute(Mixer: hMixerObj; var Control: TMixerControl): MMResult;
  // Returns True on success
var
  Line: TMixerLine;
  Controls: TMixerLineControls;
begin
  ZeroMemory(@Line, SizeOf(Line));
  Line.cbStruct := SizeOf(Line);
  Line.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
  Result := mixerGetLineInfo(Mixer, @Line, MIXER_GETLINEINFOF_COMPONENTTYPE);
  if Result = MMSYSERR_NOERROR then
  begin
    ZeroMemory(@Controls, SizeOf(Controls));
    Controls.cbStruct := SizeOf(Controls);
    Controls.dwLineID := Line.dwLineID;
    Controls.cControls := 1;
    Controls.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE;
    Controls.cbmxctrl := SizeOf(Control);
    Controls.pamxctrl := @Control;
    Result := mixerGetLineControls(Mixer, @Controls,
      MIXER_GETLINECONTROLSF_ONEBYTYPE);
  end;
end;

procedure SetMasterMuteValue(Mixer: hMixerObj; Value: Boolean);
var
  MasterMute: TMixerControl;
  Details: TMixerControlDetails;
  BoolDetails: TMixerControlDetailsBoolean;
  Code: MMResult;
begin
  Code := GetMasterMute(0, MasterMute);
  if Code = MMSYSERR_NOERROR then
  begin
    with Details do
    begin
      cbStruct := SizeOf(Details);
      dwControlID := MasterMute.dwControlID;
      cChannels := 1;
      cMultipleItems := 0;
      cbDetails := SizeOf(BoolDetails);
      paDetails := @BoolDetails;
    end;
    LongBool(BoolDetails.fValue) := Value;
    Code := mixerSetControlDetails(0, @Details,MIXER_SETCONTROLDETAILSF_VALUE);
  end;
  if Code <> MMSYSERR_NOERROR then
    raise Exception.CreateFmt('SetMasterMuteValue failure, ' + 'multimedia system error #%d', [Code]);
end;

// Example:

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetMasterMuteValue(0, CheckBox1.Checked); // Mixer device #0 mute on/off
end;

Leave a Comment