Archive for June, 2010

TValueListEditor OnValidate

TValueListEditor에서 입력한 값을 Validation하려고 봤더니 Validate에 뭔가 이상합니다. OnValidate 이벤트에 성공/ 실패가 있을줄 알았더니만 없네..

그래서 OnValidate에 아래처럼하고

procedure TValueListEditorForm.ValueListEditor1Validate(Sender: TObject; ACol,
  ARow: Integer; const KeyName, KeyValue: string);
begin
  if Trim(KeyValue) = '' then
    FValidateFailed := True;
end;

선택을 못하게.. ㅋㅋ

procedure TValueListEditorForm.ValueListEditor1SelectCell(Sender: TObject; ACol,
  ARow: Integer; var CanSelect: Boolean);
begin
  if FValidateFailed then
  begin
    CanSelect := False;
    FValidateFailed := False;
  end;
end;

Drag and Drop Component Suite를 이용한 탐색기에 파일 저장 그리고..

Drag and Drop Component Suite를 이용해 어제 오늘 놀고 있습니다. 이걸로

  1. ListView에 파일 목록이 있고 이를 탐색기로 Drag&Drop로 저장
  2. 파일의 데이터는 실제 파일이 아니고 Application에서 생성하는 데이터
  3. Drag&Drop으로 ListView안에서 위치 조절

와 같은 일을 하고자 합니다. 1, 2 번은 Drag&Drop Suite에서 제공해주는 TVirtualFileStreamDataFormat을 이용해서 하면 되는데, 마지막 리스트 안에서 위치조절하는 것은 복잡하네요.

Shell로 Drag&Drop이 없으면 간단히 델파이에서 제공하는 기능을 이용하면 되는데, Drag&Drop Suite와 같이 쓰면 이것이 안됩니다. 둘중에 하나만 사용해야하는 현상이 발생합니다(이것때문에 삽질좀 하고..).

결국은 TCustomDataFormat을 이용해서 2가지 데이터 형태를 같이 사용해서 해결했습니다. 자세한 내용은 코드확인!

DragDropShellAndVCL



Controls.CancelDrag는 dmAutomatic은 안되네..

CancelDrag로 Drag&Drop operation을 취소하려는데, DragMode=dmAutomatic인 상태에서 시작한 Drag&Drop은 취소가 되지 않는구나...


ListView의 SubItem에 ProgressBar 그리기

TListView에 ProgressBar를 표현하는 것을 간단하게 생각하면 TProgressBar를 생성하고 SubItem위치에 표시하면 됩니다. 그리고 컬럼이 사이즈가 조절될 때 (HeaderTracking) 적당하게 위치 조절해주면 됩니다. 간단하게 심플하게 생각하면 그렇지요.

근데 그냥 OnDrawSubItem 이벤트에서 Themes을 이용해서 그려주면 어떨까? 하고 해 봤는데, 생각보다 간단합니다.

procedure TThemeForm.ListView1CustomDrawSubItem(Sender: TCustomListView;
  Item: TListItem; SubItem: Integer; State: TCustomDrawState;
  var DefaultDraw: Boolean);
var
  Element: TThemedElementDetails;
  R: TRect;
  Progress: 1..100;
begin
  if ((Sender as TListView).ViewStyle = vsReport) and (SubItem = 3) then
  begin
    R := Item.SubItemRect(SubItem, drBounds);
    Inc(R.Left);
    if Sender.GridLines then Dec(R.Bottom);

    Element := ThemeServices.GetElementDetails(tpBar);
    ThemeServices.DrawElement(Sender.Canvas.Handle, Element, R);

    Element := ThemeServices.GetElementDetails(tpChunk);
    InflateRect(R, -4, -3);
    Progress := 30;
    R.Right := R.Left + MulDiv(Progress, R.Right - R.Left, 100);
    ThemeServices.DrawElement(Sender.Canvas.Handle, Element, R);

    DefaultDraw := False;
  end;
end;

SubItemRect 함수는 다음과 같습니다.

function TListItemHelper.SubItemRect(SubItemIndex: Integer; Code: TDisplayCode): TRect;
const
  Codes: array[TDisplayCode] of Longint = (LVIR_BOUNDS, LVIR_ICON, LVIR_LABEL,
    LVIR_SELECTBOUNDS);
begin
  ListView_GetSubItemRect(ListView.Handle, Index, SubItemIndex, Codes[Code], @Result);
end;

자 잘나옵니까?


nginx가 꽤 괜찮은가 본데?

RubyOnRails를 해볼 일이 생겼습니다. 기회가 없어서 하지않았던 건데.. 어쩌다보니 이것도 돌아보게 되었네요.

여기저기 문서를 뒤지다보다 보니 nginx에 대한 언급이 되고있고 특히 nginx에 대해서 눈에 띄는건 성능이 굉장이 좋다는 군요. 홈페이지 about에 소개된 FastFail.FM, WordPress.com의 예를 둘러보니 시도해볼까? 하는 생각이 듭니다.

Apache를 현재 무리없이 쓰고있지만, 어느 순간부턴 느낌이 너무 복잡해졌다고나할까? 하여간 그런 느낌이 들고, 요즘은 웹 서버에서는 연결받고 Application server로 바로 넘기는 일 밖에 안하나 이런 일에 충실한 웹 서버면 충분 하겠지요.

시간나면 해봐야죠. ㅋㅋ


The Complete Idiot’s Guide to Writing Shell Extensions

Shell extension에 관심있다면 쭈욱 봐야겠다

The Complete Idiot's Guide to Writing Shell Extensions

  • Context menu handler: 파일 또는 폴더 context menu에 항목 추가하기
  • Property sheet handler: 파일의 속성 대화상자 탭 추가하기
  • Drag and drop handler
  • Drop handler
  • Query info handler


마우스 휠메시지를 포커스가 있는 컨트럴이 아닌 마우스가 위치한 컨트럴로 보내기

{
  마우스 휠을 움직이면 포커스가 있는 컨트럴에 WM_MOUSEWHEEL이 가는데, 다른
  Application을 보면 마우스 포인터가 위치한 컨트럴에서 반응을 하는 경우가 있다.

  이 유닛을 포함하면 WM_MOUSEWHEEL 메시지가 마우스 커서가 있는 컨트럴로 간다.
  따라서 마우스 클릭을 하여 포커스를 이동할 필요가 없다.
}
unit WMMouseWheelUnderCursor;

interface

implementation

uses
  Windows, Forms, Classes, AppEvnts, Messages, Controls;

type
  TWMMouseWheelMessageUnderCursor = class(TApplicationEvents)
  private
    procedure OnMessageHandler(var Msg: tagMSG; var Handled: Boolean);

  public
    constructor Create(AOwner: TComponent); override;
  end;

{ TWMMouseWheelMessageUnderCursor }

constructor TWMMouseWheelMessageUnderCursor.Create(AOwner: TComponent);
begin
  inherited;

  OnMessage := OnMessageHandler;
end;

procedure TWMMouseWheelMessageUnderCursor.OnMessageHandler(var Msg: tagMSG;
  var Handled: Boolean);
var
  Pt: TPoint;
  Control: TWinControl;
begin
  if Msg.message = WM_MOUSEWHEEL then
  begin
    Pt.X := Word(Msg.lParam);
    Pt.Y := HiWord(Msg.lParam);
    Control := FindVCLWindow(Pt);
    if not Assigned(Control) then
      Handled := True
    else if Control.Handle <> Msg.hwnd then
    begin
      Handled := True;
      SendMessage(Control.Handle, WM_MOUSEWHEEL, Msg.wParam, Msg.lParam);
    end;
  end;
end;

initialization
  TWMMouseWheelMessageUnderCursor.Create(Application);

end.

msbuild를 이용해서 컴파일할때 map 정보넣기..

JclDebug Expert를 이용해서 실행파일에다가 map파일 정보를 넣는건 쉽습니다. 그냥 메뉴에서 선택해주면 알아서 하니깐요.

하지만 우리 프로젝트에서는 msbuild를 이용해서 빌드를 하는데, 이걸로하면 JclDebug Expoert가 동작하지 않아서 map파일이 들어가지 않습니다. 흠..

이걸 어떻게 하나고 뒤져보니 Jcl에 이미 프로그램이 들어가있습니다. 하지만 소스만 들어가 있이니 컴파일해서 적용하면 되겠지요.

  1. msbuild MyProg.dproj /t:build /p:Configuration=Release /p:DCC_Define=RELEASE /p:DCC_MapFile=3
    빌드할때 맵파일을 생성합니다.
  2. MakeJclDebug -E MyProg.map
    컴파일이 끈나면 map파일을 압축해서 프로그램 바이너리에 집어넣습니다.

이렇게 하고 JclDebug에서 제공하는 ExceptionDialog가 실행되면 자동으로 바이너리의 map파일을 이용해서 StackTrace를 출력해줍니다.


  • Copyright © 1996-2010 Your wish is my command. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress