BLOG main image
분류 전체보기 (65)
JSP (6)
Android (1)
ASP.NET (0)
MSSQL (4)
PHP (18)
ASP (11)
오픈 API (1)
HTML (2)
JavaScript (0)
Windows Programming (8)
컴퓨터교양 (14)
객체 지향 (0)
리뷰 및 생각 (0)
Visitors up to today!
Today hit, Yesterday hit
daisy rss
tistory 티스토리 가입하기!
'Delphi'에 해당되는 글 7건
2010. 9. 13. 22:00
검색기를 만들 때 엔터 처리를 하려면, 사용자가 입력한 키와 Virtual Key를 비교 해야 한다.

아래는 이에 해당하는 코드이다.

procedure TfrmMain.edtSearchKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then
    btnSearch.Click;
end;

아래는 Virtual Key Codes를 정리해 놓은 표이다.

출처 : http://delphi.about.com/od/objectpascalide/l/blvkc.htm

Symbolic
constant name
Value
(hexadecimal)
Keyboard (or mouse) equivalent
VK_LBUTTON 01 Left mouse button
VK_RBUTTON 02 Right mouse button
VK_CANCEL 03 Control-break processing
VK_MBUTTON 04 Middle mouse button (three-button mouse)
VK_BACK 08 BACKSPACE key
VK_TAB 09 TAB key
VK_CLEAR 0C CLEAR key
VK_RETURN 0D ENTER key
VK_SHIFT 10 SHIFT key
VK_CONTROL 11 CTRL key
VK_MENU 12 ALT key
VK_PAUSE 13 PAUSE key
VK_CAPITAL 14 CAPS LOCK key
VK_ESCAPE 1B ESC key
VK_SPACE 20 SPACEBAR
VK_PRIOR 21 PAGE UP key
VK_NEXT 22 PAGE DOWN key
VK_END 23 END key
VK_HOME 24 HOME key
VK_LEFT 25 LEFT ARROW key
VK_UP 26 UP ARROW key
VK_RIGHT 27 RIGHT ARROW key
VK_DOWN 28 DOWN ARROW key
VK_SELECT 29 SELECT key
VK_PRINT 2A PRINT key
VK_EXECUTE 2B EXECUTE key
VK_SNAPSHOT 2C PRINT SCREEN key
VK_INSERT 2D INS key
VK_DELETE 2E DEL key
VK_HELP 2F HELP key
30 0 key
31 1 key
32 2 key
33 3 key
34 4 key
35 5 key
36 6 key
37 7 key
38 8 key
39 9 key
41 A key
42 B key
43 C key
44 D key
45 E key
46 F key
47 G key
48 H key
49 I key
4A J key
4B K key
4C L key
4D M key
4E N key
4F O key
50 P key
51 Q key
52 R key
53 S key
54 T key
55 U key
56 V key
57 W key
58 X key
59 Y key
5A Z key
VK_NUMPAD0 60 Numeric keypad 0 key
VK_NUMPAD1 61 Numeric keypad 1 key
VK_NUMPAD2 62 Numeric keypad 2 key
VK_NUMPAD3 63 Numeric keypad 3 key
VK_NUMPAD4 64 Numeric keypad 4 key
VK_NUMPAD5 65 Numeric keypad 5 key
VK_NUMPAD6 66 Numeric keypad 6 key
VK_NUMPAD7 67 Numeric keypad 7 key
VK_NUMPAD8 68 Numeric keypad 8 key
VK_NUMPAD9 69 Numeric keypad 9 key
VK_SEPARATOR 6C Separator key
VK_SUBTRACT 6D Subtract key
VK_DECIMAL 6E Decimal key
VK_DIVIDE 6F Divide key
VK_F1 70 F1 key
VK_F2 71 F2 key
VK_F3 72 F3 key
VK_F4 73 F4 key
VK_F5 74 F5 key
VK_F6 75 F6 key
VK_F7 76 F7 key
VK_F8 77 F8 key
VK_F9 78 F9 key
VK_F10 79 F10 key
VK_F11 7A F11 key
VK_F12 7B F12 key
VK_F13 7C F13 key
VK_F14 7D F14 key
VK_F15 7E F15 key
VK_F16 7F F16 key
VK_F17 80H F17 key
VK_F18 81H F18 key
VK_F19 82H F19 key
VK_F20 83H F20 key
VK_F21 84H F21 key
VK_F22 85H F22 key
VK_F23 86H F23 key
VK_F24 87H F24 key
VK_NUMLOCK 90 NUM LOCK key
VK_SCROLL 91 SCROLL LOCK key
VK_LSHIFT A0 Left SHIFT key
VK_RSHIFT A1 Right SHIFT key
VK_LCONTROL A2 Left CONTROL key
VK_RCONTROL A3 Right CONTROL key
VK_LMENU A4 Left MENU key
VK_RMENU A5 Right MENU key
VK_PLAY FA Play key
VK_ZOOM FB Zoom key
2010. 9. 13. 03:03
디렉토리 다이알로그 띄우기 : http://bloodguy.tistory.com/entry/Delphi-%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC-%EC%84%A0%ED%83%9D-Dialog-%EB%9D%84%EC%9A%B0%EA%B8%B0

위 글을 찾은 이유는 한 폴더속에 있는 파일들을, 사용자가 지정한 폴더에 복사해야 할 일이 생겼기 때문이다.
아래는 이 작업에 대한 코드 조각이다.

var
  srcDir, descDir : String;
  sr : TSearchRec;
  srcFullPath, descFullPath : String;
begin
  // 사용자가 폴더를 지정했으면
  if SelectDirectory('','',descDir) then
  begin
    // 파일을 끄집어 내기 위한 준비를 한다. TSearchRec의 인스턴스를 초기화 한다.
    if FindFirst(srcDir, faArchive, sr) = 0 then
      // sr에서 파일을 하나씩 끄집어 내서 복사 한다.
      while FindNext(sr) = 0 do begin
        srcFullPath := PChar(ExtractFilePath(srcDir) + sr.Name);
        descFullPath := PChar(descDir + '\' + sr.Name);
        CopyFile(PChar(srcFullPath), PChar(descFullPath), False);
      end;
    FindClose(sr);
  end;
end;
2010. 9. 13. 02:51

ShellExecute()는 윈도우쉘 명령을 실행시킬 때 쓰는 함수이다.
내가 사용하는 용도는 두가지이다.
한가지는 탐색기를 열 때(지정한 폴더로 이동시키는 것 까지),
나머지 한가지는 파일(윈도우즈 확장자 연결 프로그램으로 등록된 확장자를 가진 파일)을 열 때 이다.

먼저 탐색기를 여는 방법이다.
ShellExecute(0, 'explore', PChar(descDir), nil, nil, SW_SHOWNORMAL);

다음으로 파일을 열 때 이다.
var
  fileFullPath : String;
  errCode : Cardinal;

begin
    errCode := ShellExecute(handle, 'open', Pchar(fileFullPath) , nil, nil, SW_SHOW);
    if errCode = 31 then ShowMessage('HWP가 설치되어 있지 않습니다'); //실행화일 없을때
    if errCode = 2 then ShowMessage('파일이 존재하지 않습니다');      //파일 없을때
end;
2010. 9. 13. 02:33

델파이는 조회 결과레코드셋에 들어 있는 바이너리를
CreateBlobStream() 함수를 이용하여 받을 수 있다.
기본적으로 stream으로 받아서 메모리에 올린 후 원하는 작업을 하면 된다.

이 코드 조각에서는 바이너리를 파일로 저장하기 위해 TMemoryStream의 SaveToFile() 프로시져를 사용하였다.

var
  code, tempFullPath: string;
  stream : TStream;
  blob : string;
  mStream : TMemoryStream;

begin
    with ADOQuery1 do begin
      if Active then Close;
      SQL.Clear;
      SQL.Text := 'SELECT binary'
                + ' FROM tablename'
                + ' WHERE code=:code';
      Parameters.ParamByName('code').Value := code;
      // 여기서 Open의 결과는 한행만을 반환한다.
      Open;
      stream := CreateBlobStream(FieldByName('binary'), bmRead);
      SetLength(blob, stream.Size);
      stream.Read(Pointer(blob)^, stream.Size);
      mStream := TMemoryStream.Create;
      mStream.Write(Pointer(blob)^, Length(blob));
      mStream.SaveToFile(tempFullPath);
    end;
end;
2010. 9. 13. 02:25

보통 ADOQuery를 사용하여 많은 조회 쿼리를 수행한다.
아래는 ADOQuery를 사용할 때 쓰이는 기본적인 코드 조각이다.

  with ADOQuery1 do begin
    if Active then Close;
    SQL.Clear;
    SQL.Text := 'SELECT * FROM tablename';
                   + ' WHERE name = :NAME;
    Parameters.ParamByName('NAME').Value := 'ojh';
    Open;
    while not Eof do begin
      // FieldByName('title').AsString;
      // FieldByName('id').AsInteger;
      Next;
    end;
    Close;
  end;
2010. 9. 13. 02:15

델파이에서 기본적으로 제공하는 DBGrid는 UI 면에서 볼 때 그리 강력하지 않다.
보통의 다른 그리드에서 제공하는 기본적인 기능이 구현되어 있지 않다.
예를 들면 컬럼명을 클릭하면 오름차순이나 내림차순으로 정렬되는 기능(Sort function)이 없고,
컬럼의 오른쪽 끝을 더블 클릭하면 내용의 길이에 따라 컬럼너비가 늘어나는 기능(Column autoFit function)이 없다.
또한 디자이너에서 그리드 외곽선을 솔리드로 만드는 기능이 없다.

이중 Column autoFit 을 구현하는 방법에 대해 기록한다.

목표 : 컬럼명을 더블 클릭하면 해당 컬림이 autoFit이 되도록 한다.
1. DBGrid1DblClick 이벤트 속에서 컬럼명이 더블클릭 되었는지 판단한다.(gridCoord.Y == 0)
2.
컬럼명이 더블클릭 되었으면 해당 컬럼을 다시 그린다.(Repaint)
3. 다시 그릴때 그려지는 텍스트들의 너비를 비교하여, 최대 너비를 구한다.(DrawColumnCell)
4. 구해진 너비를 컬럼너비에 대입한다.

아래 소스처럼 구현 하면 된다. 자세한 설명은 나중에...



출처 : http://delphi.about.com/od/usedbvcl/a/dbgrid_autofit.htm

 type
  TColumnWidthHelper = record
   Index : integer;
   MaxWidth : integer;
  end;

procedure TForm1.DBGrid1DblClick(Sender: TObject) ;
var
   mouseInGrid : TPoint;
   gridCoord: TGridCoord;
begin
  //Convert "Screen" Mouse to "Grid" Mouse
  mouseInGrid := DBGrid1.ScreenToClient(Mouse.CursorPos) ;
  gridCoord := DBGrid1.MouseCoord(mouseInGrid.X, mouseInGrid.Y) ;

  //Column titles NOT displayed?
  if not (dgTitles in DBGrid1.Options) then Exit;

  //Titles displayed but we double-clicked on "regular" row?
  if gridCoord.Y <> 0 then Exit;

  //find Column index
  if dgIndicator in DBGrid1.Options then
    ColumnWidthHelper.Index := -1 + gridCoord.x
  else
    ColumnWidthHelper.Index := gridCoord.x;

  //Indicator Column?
  if ColumnWidthHelper.Index < 0 then Exit;
... // continues below When we are sure that a column title was double clicked we can find the widest entry in that column and set column width ...
    //continues from above ...

    ColumnWidthHelper.MaxWidth := -1;
 
    //"recalculate" ColumnWidthHelper.MaxWidth
    DBGrid1.Repaint;
 
    //"auto size" Column width
    DBGrid1.Columns[ColumnWidthHelper.Index].Width := 4 + ColumnWidthHelper.MaxWidth;
 end;
 
//The trick is in the DBGrid1.Repaint call. This forces the grid to repaint itself thus fireing the DrawColumnCell event (for all the visible rows).
 procedure TForm1.DBGrid1DrawColumnCell(
    Sender: TObject;
    const Rect: TRect;
    DataCol: Integer;
    Column: TColumn;
    State: TGridDrawState) ;
 begin
   //is this is the column we want to auto-size?
   if DataCol = ColumnWidthHelper.Index then
   begin
    //Column has field?
    if Assigned(Column.Field) then
    begin
     //find the widest string
     ColumnWidthHelper.MaxWidth := Max(ColumnWidthHelper.MaxWidth, DBGrid1.Canvas.TextWidth(Column.Field.DisplayText)) ;
    end;
   end;
 end; 
2010. 9. 13. 00:56

델파이에서 기본적으로 제공하는 DBGrid에는 한가지 문제점이 있다.
그리드에서 마우스 스크롤을 한 뒤 원하는 셀을 클릭해보면 원치 않는 행이 선택되는 것을 볼 수 있다.
마우스 스크롤을 아랫쪽으로 스크롤을 하면 실제 커서 포인터는 위로 이동하고,
반대로 마우스 스크롤을 윗쪽으로 스크롤을 하면 실제 커서 포인터는 아래로 이동한다.

이것은 DBGrid가 Visible 부분은 잘 처리하는데, 커서 부분은 잘 처리하지 못하는 문제이다.
따라서 마우스 스크롤시 커서 부분을 잘 처리시켜줘야 한다.

잘 처리하는 방법은 WndProc에 새로운 메시지 처리기를 등록하고, WM_MOUSEWHEEL 쪽을 알맞게 구현하면 된다.
아래 소스처럼 구현 하면 된다. 자세한 설명은 나중에...



출처 : http://www.delphi3000.com/articles/article_3892.asp?SK=DBGrid

type
  TomaInvento = class(TControl);

//So we can, later on, substitute the WndProc of DBGrid1 with an instruction similar to:

  DBGrid1.WindowProc := DBGrid1PillaLaRueda;

//for example in "Oncreate" of our Form
//Here you have the Unit of a form in which I have placed a DBGrid a TTable and a TDataSource to check all the invention


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Grids, DBGrids, Db, DBTables;

type
  TForm1 = class(TForm)
    Table1: TTable;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure DBGrid1PillaLaRueda(var Message: TMessage);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

type
  TomaInvento = class(TControl);

procedure TForm1.DBGrid1PillaLaRueda(var Message: TMessage);
var
  Cuanto : short;
begin
  if (Message.Msg = WM_MOUSEWHEEL) then begin
    Cuanto:=HIWORD(Message.WParam);
    Cuanto:=Cuanto div 120;
    DbGrid1.DataSource.DataSet.MoveBy(-Cuanto)
  end else TomaInvento(DBGrid1).WndProc(Message);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  DBGrid1.WindowProc := DBGrid1PillaLaRueda;
end;

end.
prev"" #1 next