ÀúÀ۱ǿ¡ ´ëÇÑ °øÁö
ÀÌ ¹®¼­¿¡ Æ÷ÇÔµÈ ¸ðµç ±Û°ú ¼Ò½º ÄÚµå´Â ÀÛÀÚÀÎ Àú ±è¼ºµ¿ÀÇ ÁöÀû Àç»êÀÌÁö¸¸ ¹«´ÜÀ¸·Î ¹èÆ÷Çϰųª Ã¥À̳ª °­ÀÇ ±³ÀçµîÀ» À§ÇÑ º¹Á¦ µî ÀúÀÛ±ÇÀ» ÀúÇØÇÏ´Â ÇàÀ§¸¦ Á¦¿ÜÇϰí´Â ÀÚÀ¯·Ó°Ô »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.
¶ÇÇÑ ÀÌ ÆäÀÌÁö¿¡ ´ëÇÑ ¸µÅ©´Â ÀÚÀ¯·Ó°Ô ÇÒ ¼ö ÀÖÀ¸³ª Àü¹®À» ÀüÁ¦ÇÏ´Â ÀÏÀº Çã¿ëÇÏÁö ¾Ê½À´Ï´Ù.


2.3. 3Â÷¿ø ·¹À̺í ÄÞÆ÷³ÍÆ® °³¹ß

µ¨ÆÄÀÌ¿¡ ±âº»ÀûÀ¸·Î Æ÷ÇԵǾî ÀÖ´Â ±âº» ÄÞÆ÷³ÍÆ®ÀÎ ¹Ô¹ÔÇÑ TLabel ÄÞÆ÷³ÍÆ®ÀÇ ±â´ÉÀ» È®ÀåÇØ¼­ ÆûÀ» Á» ´õ È­·ÁÇÏ°Ô ±¸¼ºÇÒ ¶§ »ç¿ëÇÒ ¼ö ÀÖ´Â 3Â÷¿ø È¿°ú¸¦ °¡Áö´Â Label ÄÞÆ÷³ÍÆ®¸¦ ¸¸µé¾î º¸ÀÚ. ¶ÇÇÑ ±¹³» ¾÷¹«¿ë ÇÁ·Î±×·¥ÀÇ °æ¿ì PanelÀ̳ª Bevel ÄÞÆ÷³ÍÆ®¸¦ ½á¼­ ÇʵåÀÇ À̸§À» °­Á¶ÇÏ´Â °æ¿ì°¡ Á¾Á¾ Àִµ¥ PanelÀ» »ç¿ëÇÑ´Ù¸é À©µµ ¸®¼Ò½º¸¦ ¸¹ÀÌ ¼Ò¸ðÇÏ°Ô µÇ¹Ç·Î Label ÄÞÆ÷³ÍÆ® ÀÚüÀûÀ¸·Î ¿Ü°û¼±À» ±×·ÁÁÖµµ·Ï ÇØ¼­ °£ÆíÇÏ°Ô »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ¸¸µé¾î º¸ÀÚ. ¿Ï¼ºµÈ ÄÞÆ÷³ÍÆ®´Â ¾Æ·¡ ±×¸²°ú °°ÀÌ µ¿ÀÛÇÑ´Ù.

±×¸² 2-11 TdpbLabel ÄÞÆ÷³ÍÆ® µ¿ÀÛ È­¸é


±×¸®°í ¿Ï¼ºµÈ ÄÞÆ÷³ÍÆ®ÀÇ ¼Ò½º´Â ¾Æ·¡ ¸®½ºÆ®¿Í °°´Ù.

¸®½ºÆ® 2.4 dpbLabel.pas
unit dpbLabel;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  { ±×·Á¾ß ÇÒ ¿Ü°û¼± }
  TdpbEdges = set of ( deLeft, deTop, deRight, deBottom );

  { ¿Ü°û¼± ¸ð¾ç }
  TdpbEdgeStyle = ( desNone, desFlat, desRaised, desRaisedHeavy, desSunken,
                    desSunkenHeavy , desBump, desEtched );

  { ÅØ½ºÆ® ¸ð¾ç }
  TdpbTextStyle = ( dtsFlat, dtsRaised, dtsRaisedHeavy, dtsSunken,
                    dtsSunkenHeavy, dtsShadow );

  { ±×¸²ÀÚ È¿°ú ¹æÇâ }
  TdpbShadowDirection = ( dsdTopLeft, dsdTopRight, dsdBottomLeft, dsdBottomRight );

  TdpbLabel = class(TCustomLabel)
  private
    { Private declarations }
    FEdges : TdpbEdges;
    FEdgeStyle : TdpbEdgeStyle;
    FTextStyle : TdpbTextStyle;
    { ±×¸²ÀÚ ¹æÇâ }
    FShadowDirection : TdpbShadowDirection;
    { ±×¸²ÀÚ »ö }
    FShadowColor : TColor;
    { ±×¸²ÀÚ ±íÀÌ }
    FShadowDepth : Integer;

    procedure SetEdges(const Value: TdpbEdges);
    procedure SetEdgeStyle(const Value: TdpbEdgeStyle);
    procedure SetShadowDepth(const Value: Integer);
    procedure SetShadowDirection(const Value: TdpbShadowDirection);
    procedure SetTextStyle(const Value: TdpbTextStyle);
    procedure SetShadowColor(const Value: TColor);
  protected
    { Protected declarations }
    procedure DoDrawEdge(ACanvas : TCanvas; var ARect : TRect);
    procedure DoDrawCaption(ACanvas : TCanvas; ARect : TRect);
  public
    { Public declarations }
    constructor Create(AOwner : TComponent); override;
    procedure Paint; override;
  published
    { Published declarations }
    property Anchors;
    property Align;
    property Alignment;
    property AutoSize;
    property Caption;
    property Color;
    property Cursor;
    property DragCursor;
    property DragMode;

    property Edges : TdpbEdges
             read FEdges
             write SetEdges
             default [deLeft, deTop, deRight, deBottom];

    property EdgeStyle : TdpbEdgeStyle
             read FEdgeStyle
             write SetEdgeStyle
             default desNone;

    property FocusControl;
    property Font;
    property Hint;
    property Layout;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;

    property ShadowColor : TColor
             read FShadowColor
             write SetShadowColor
             default clBtnShadow;

    property ShadowDirection : TdpbShadowDirection
             read FShadowDirection
             write SetShadowDirection
             default dsdBottomRight;

    property ShadowDepth : Integer
             read FShadowDepth
             write SetShadowDepth
             default 1;

    property ShowAccelChar;
    property ShowHint;

    property TextStyle : TdpbTextStyle
             read FTextStyle
             write SetTextStyle
             default dtsFlat;

    property Transparent;
    property WordWrap;

    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDrag;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('DPB', [TdpbLabel]);
end;

{ TdpbLabel }

constructor TdpbLabel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FEdges := [deLeft, deTop, deRight, deBottom];
  FEdgeStyle := desNone;
  FTextStyle := dtsFlat;
  FShadowDirection := dsdBottomRight;
  FShadowDepth := 1;
  FShadowColor := clBtnShadow;
end;

procedure TdpbLabel.DoDrawCaption(ACanvas: TCanvas; ARect: TRect);
const
  Alignments: array[TAlignment] of WORD = (DT_LEFT, DT_RIGHT, DT_CENTER);
  WordWraps: array[Boolean] of WORD = (0, DT_WORDBREAK);
  ShowAccel : array[Boolean] of WORD = (DT_NOPREFIX, 0);
var
  TextFlag : WORD;
  rDraw, rExtent : TRect;
  TE : TSize;
begin
  with ACanvas do
  begin
    rExtent := ARect;
    Font.Assign(Self.Font);
    Brush.Style := bsClear;
    TextFlag := DT_EXPANDTABS Or WordWraps[WordWrap] Or
                ShowAccel[ShowAccelChar] or Alignments[Alignment];
    DrawText(Handle, PChar(Caption), -1, rExtent, TextFlag Or DT_CALCRECT);
    TE.CX := rExtent.Right - rExtent.Left;
    TE.CY := rExtent.Bottom - rExtent.Top;
    rDraw := ARect;
    case Layout of
      tlCenter :
        rDraw.Top := rDraw.Top + ((rDraw.Bottom - rDraw.Top) - 
(rExtent.Bottom - rExtent.Top)) div 2;
      tlBottom :
        rDraw.Top := rDraw.Top + ((rDraw.Bottom - rDraw.Top) - 
(rExtent.Bottom - rExtent.Top));
    end;

    case FTextStyle of
      dtsFlat :
        begin
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
        end;
      dtsRaised :
        begin
          OffsetRect(rDraw, -1, -1);
          Font.Color := clBtnHighlight;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
          OffsetRect(rDraw, 1, 1);
          Font.Color := Self.Font.Color;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
        end;
      dtsRaisedHeavy :
        begin
          OffsetRect(rDraw, -1, -1);
          Font.Color := clBtnHighlight;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
          OffsetRect(rDraw, 2, 2);
          Font.Color := FShadowColor;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
          OffsetRect(rDraw, -1, -1);
          Font.Color := Self.Font.Color;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
        end;
      dtsSunken :
        begin
          OffsetRect(rDraw, 1, 1);
          Font.Color := clBtnHighlight;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
          OffsetRect(rDraw, -1, -1);
          Font.Color := Self.Font.Color;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
        end;
      dtsSunkenHeavy :
        begin
          OffsetRect(rDraw, -1, -1);
          Font.Color := FShadowColor;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
          OffsetRect(rDraw, 2, 2);
          Font.Color := clBtnHighlight;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
          OffsetRect(rDraw, -1, -1);
          Font.Color := Self.Font.Color;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
        end;
      dtsShadow :
        begin
          rExtent := rDraw;
          Case FShadowDirection Of
            dsdTopLeft :
            begin
              OffsetRect(rExtent, -FShadowDepth, -FShadowDepth);
            end;
            dsdTopRight :
            begin
              OffsetRect(rExtent, FShadowDepth, -FShadowDepth);
            end;
            dsdBottomLeft :
            begin
              OffsetRect(rExtent, -FShadowDepth, FShadowDepth);
            end;
            dsdBottomRight :
            begin
              OffsetRect(rExtent, FShadowDepth, FShadowDepth);
            end;
          end;
          Font.Color := FShadowColor;
          DrawText(Handle, PChar(Caption), -1, rExtent, TextFlag);
          Font.Color := Self.Font.Color;
          DrawText(Handle, PChar(Caption), -1, rDraw, TextFlag);
        end;
    end;
    Brush.Style := bsSolid;
  end;
end;

procedure TdpbLabel.DoDrawEdge(ACanvas: TCanvas; var ARect: TRect);
const
  ST : array[TdpbEdgeStyle] of WORD = (0,
       BDR_RAISEDOUTER, BDR_RAISEDOUTER, EDGE_RAISED, BDR_SUNKENOUTER,
       EDGE_SUNKEN, EDGE_BUMP, EDGE_ETCHED);
var
  Edge : WORD;
begin
  if FEdgeStyle <> desNone then
  begin
    Edge := 0;
    if deLeft in FEdges then Edge := Edge or BF_LEFT;
    if deTop in FEdges then Edge := Edge or BF_TOP;
    if deRight in FEdges then Edge := Edge or BF_RIGHT;
    if deBottom in FEdges then Edge := Edge or BF_BOTTOM;
    if FEdgeStyle = desFlat then Edge := Edge or BF_FLAT;
    DrawEdge(ACanvas.Handle, ARect, ST[FEdgeStyle], Edge or BF_ADJUST);
  end;
end;

procedure TdpbLabel.Paint;
var
  rClient : TRect;
begin
  with Canvas do
  begin
    rClient := GetClientRect;
    if not Transparent then
    begin
      Brush.Color := Self.Color;
      FillRect(rClient);
    end;
    DoDrawEdge(Canvas, rClient);
    DoDrawCaption(Canvas, rClient);
  end;
end;

procedure TdpbLabel.SetEdges(const Value: TdpbEdges);
begin
  if FEdges <> Value then
  begin
    FEdges := Value;
    Invalidate;
  end;
end;

procedure TdpbLabel.SetEdgeStyle(const Value: TdpbEdgeStyle);
begin
  if FEdgeStyle <> Value then
  begin
    FEdgeStyle := Value;
    Invalidate;
  end;
end;

procedure TdpbLabel.SetShadowColor(const Value: TColor);
begin
  if FShadowColor <> Value then
  begin
    FShadowColor := Value;
    Invalidate;
  end;
end;

procedure TdpbLabel.SetShadowDepth(const Value: Integer);
begin
  if FShadowDepth <> Value then
  begin
    FShadowDepth := Value;
    Invalidate;
  end;
end;

procedure TdpbLabel.SetShadowDirection(const Value: TdpbShadowDirection);
begin
  if FShadowDirection <> Value then
  begin
    FShadowDirection := Value;
    Invalidate;
  end;
end;

procedure TdpbLabel.SetTextStyle(const Value: TdpbTextStyle);
begin
  if FTextStyle <> Value then
  begin
    FTextStyle := Value;
    Invalidate;
  end;
end;

end.


2.3.1. 3Â÷¿ø È¿°ú
Label ÄÞÆ÷³ÍÆ®ÀÇ Ä¸¼ÇÀ» 3Â÷¿øÀ¸·Î ±×¸®´Â µ¥ ÇÊ¿äÇÑ Á¤º¸¸¦ °¡Áú ÇÁ·ÎÆÛƼ·Î ShadowColor, ShadowDepth, ShadowDirection, TextStyle ÀÌ·¸°Ô 4°³ÀÇ ÇÁ·ÎÆÛƼ¸¦ ¸¸µé¾ú´Ù. ShadowDepth, ShadowDirectionÀº ¸ðµÎ TextStyle ÇÁ·ÎÆÛƼ°¡ dtsShadowÀÏ ¶§¸¸ »ç¿ëÇÑ´Ù. ShadowColor´Â ±×¸²ÀÚ È¿°ú¸¦ ³ªÅ¸³¾ »öÀ» ÁöÁ¤Çϸç ShadowDepth´Â ±×¸²ÀÚ È¿°ú¸¦ ±×¸± ±íÀ̸¦ ³ªÅ¸³½´Ù. ShadowDirectionÀº ±×¸²ÀÚ È¿°ú°¡ ³ªÅ¸³¯ ¹æÇâÀ» ¼³Á¤ÇÏ´Â ÇÁ·ÎÆÛƼ´Ù. ShadowDirection°ú TextStyleÀº ¿­°ÅÇü ÇÁ·ÎÆÛƼ·Î ¼±¾ðµÇ¾ú´Ù.
´ÙÀ½¿¡ ÄÞÆ÷³ÍÆ®ÀÇ ¿Ü°û¼±À» ±×¸®±â À§Çؼ­ Edges ¶ó´Â ÁýÇÕÇü ÇÁ·ÎÆÛƼ¿Í EdgeStyleÀ̶ó´Â ¿­°ÅÇü ÇÁ·ÎÆÛƼ¸¦ ¸¸µé¾ú´Ù. Edges ÇÁ·ÎÆÛƼ´Â »ç°¢Çü¿¡¼­ ¼±ÅÃµÈ Edge¸¸ ¿Ü°û¼±À» ±×¸®µµ·Ï ¼³Á¤ÇÏ´Â µ¥ »ç¿ëÇϸç EdgeStyleÀº ¿Ü°û¼±¿¡ 3Â÷¿ø È¿°ú¸¦ ÁÖ±â À§Çؼ­ »ç¿ëÇÑ´Ù.
2.3.2. ±×¸®±â
½ÇÁ¦·Î ±×¸²À» ±×¸®´Â ·çƾÀº Paint ¸Þ¼Òµå¸¦ ¿À¹ö¶óÀ̵åÇØ¼­ ÀÛ¼ºÇÑ´Ù. TCustomLabelÀÇ Paint ¸Þ¼Òµå¸¦ º¸¸é ¸¶Áö¸·¿¡ DoDrawText ÇÁ·Î½ÃÀú¸¦ È£ÃâÇÏ´Â °ÍÀ» º¼ ¼ö Àִµ¥ TCustomLabel¿¡¼­ ½ÇÁ¦·Î ĸ¼ÇÀ» Ãâ·ÂÇÏ´Â ·çƾÀº ¹Ù·Î ÀÌ DoDrawText¶ó´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ±×·¸´Ù¸é ¿ì¸®°¡ ¸¸µé TdpbLabel¿¡¼­ DoDrawText¸¦ ¿À¹ö¶óÀ̵å ÇØ¼­ ±×·Á ÁÖ¸é µÇ°Ú´Ù¶ó°í »ý°¢µÇÁö¸¸ ¾ÈŸ±õ°Ôµµ DoDrawText´Â °¡»ó ¸Þ¼Òµåµµ ¾Æ´Ï°í ´õ±º´Ù³ª private ¿µ¿ª¿¡ ¼±¾ðµÇ¾î ÀÖ´Ù. µû¶ó¼­ ºÎµæÀÌ Paint ¸Þ¼Òµå¸¦ ¿À¹ö¶óÀ̵å ÇØ¼­ ±×¸²À» ±×·Á ÁÙ ¼ö ¹Û¿¡ ¾ø´Ù. ÄÞÆ÷³ÍÆ®¸¦ °³¹ßÇÒ ¶§ ºÎ¸ð Ŭ·¡½ºÀÇ ¼Ò½º Äڵ尡 ÀÖ´Ù¸é ºÎ¸ð Ŭ·¡½º¿¡ ³»°¡ Á¤ÀÇÇÏ·Á°í ÇÏ´Â ±â´ÉÀÌ ¾ø´ÂÁö Àß »ìÆìº¸°í ¾î¶² ½ÄÀ¸·Î ±¸ÇöÇÏ´Â °ÍÀÌ ÈξÀ È¿°úÀûÀÏÁö Àß »ý°¢Çؼ­ °³¹ßÇØ¾ß ÇÑ´Ù. ±×·¡¾ß ÄÞÆ÷³ÍÆ®ÀÇ Äڵ尡 ÃÖÀûÈ­µÇ°í ºÒÇÊ¿äÇÑ Äڵ尡 µé¾î°¡´Â ÀÏÀ» ÃÖ¼ÒÈ­ ÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.
ºÎ¸ð Ŭ·¡½ºÀÎ TCustomLabelÀÌ ±×¸®´Â ·çƾÀº Çʿ䰡 ¾øÀ¸¹Ç·Î Inherited Paint ¹®ÀåÀ» »ç¿ëÇÏÁö ¾Ê¾Ò´Ù. ½ÇÁ¦·Î ĸ¼Ç°ú ¿Ü°û¼±À» ±×¸®´Â ÇÁ·Î½ÃÀúÀÎ DoDrawEdge, DoDrawCaption ÇÁ·Î½ÃÀú´Â protected ¿µ¿ª¿¡ ¸¸µé¾ú´Ù. ºÎ¸ð Ŭ·¡½º¿¡¼­ Àû¿ëµÇ´Â ¸î°¡Áö ÇÁ·ÎÆÛƼ ¿¹¸¦ µé¾î Alignment, Layout, Transparent, ShowAccelCharµîÀÌ ÇÊ¿ä ¾ø´Â ÇÁ·ÎÆÛƼ°¡ µÇÁö ¾Êµµ·Ï À̵é ÇÁ·ÎÆÛƼÀÇ °ªµµ °í·ÁÇØ¼­ ±×¸®´Â Paint ·çƾÀ» ¸¸µç´Ù.
ĸ¼ÇÀ» 3Â÷¿øÀ¸·Î ±×¸®´Â ¿ø¸®´Â ¼Ò½º Äڵ带 »ìÆì º¸¸é ½±°Ô ¾Ë ¼ö ÀÖÀ» °ÍÀÌ´Ù. ±ÛÀÚ¸¦ Ãâ·ÂÇÏ´Â À§Ä¡¿Í ±ÛÀÚÀÇ »ö±òÀ» ÀûÀýÇÑ ¼ø¼­´ë·Î º¯°æÇذ¡¸é¼­ Ãâ·ÂÇØ ÁÖ¸é °£´ÜÇÏ°Ô 3Â÷¿ø È¿°ú¸¦ ±¸ÇöÇÒ ¼ö ÀÖ´Ù. ±ÛÀÚ¸¦ Ãâ·ÂÇÒ ¶§ CanvasÀÇ TextOutÀ̳ª TextRect¸¦ »ç¿ëÇÏÁö ¾Ê°í À©µµ APIÀÎ DrawText¸¦ »ç¿ëÇÑ ÀÌÀ¯´Â TextOutÀ̳ª TextRect´Â DrawText¸¦ °£´ÜÇÏ°Ô »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇØ ³õÀº ¸Þ¼Òµå¶ó¼­ DrawText¸¸Å­ Ç÷¡±×¸¦ ÀÌ¿ëÇØ¼­ ´Ù¾çÇÏ°Ô Ãâ·ÂÇÒ ¼ö ¾ø±â ¶§¹®ÀÌ´Ù.
¿Ü°û¼±µµ ¸¶Âù°¡Áö·Î CanvasÀÇ ¸Þ¼Òµå¿¡´Â DrawEdgeó·³ °£´ÜÇÏ°Ô 3Â÷¿ø »ç°¢ÇüÀ» ±×¸®´Â ¸Þ¼Òµå°¡ ¾ø±â ¶§¹®¿¡ À©µµ GDI APIÀÎ DrawEdge ÇÔ¼ö¸¦ ÀÌ¿ëÇß´Ù.

2.4. ½© º¯È­ °¨Áö ÄÞÆ÷³ÍÆ® °³¹ß

À©µµ Ž»ö±â¸¦ µÎ °³ ¶ç¿ö ³õ°í ÇÑÂÊ Å½»ö±â¿¡¼­ ÆÄÀÏÀ» »èÁ¦Çϰųª »õ ÆÄÀÏÀ» ¸¸µé¸é ´Ù¸¥ Ž»ö±â¿¡µµ ±× ³»¿ëÀÌ ¶È °°ÀÌ ¹Ý¿µµÇ´Â °ÍÀ» º¼ ¼ö ÀÖ´Ù. ¶ÇÇÑ »ó¿ë ÅØ½ºÆ® ÆíÁý±âµîÀ» º¸¸é ÀڱⰡ ÆíÁýÇϰí ÀÖ´Â ÆÄÀÏÀÌ ´Ù¸¥ ÇÁ·Î±×·¥¿¡ ÀÇÇØ »èÁ¦µÇ°Å³ª ³»¿ëÀÌ º¯°æµÇ¾ú´Ù´Â °ÍÀ» ¾Ë°í ´Ù½Ã ÀÐ¾î µéÀÏÁö¸¦ ¹°¾î º¸´Â °æ¿ì°¡ ÀÖ´Ù. À©µµ ½Ã½ºÅÛ µð·ºÅ丮¿¡ ÀÖ´Â shell32.dllÀº µî·ÏµÈ À©µµ¿¡ ´ëÇØ À©µµ ½©¿¡ º¯È­°¡ »ý±â¸é(À̺¥Æ®) µî·ÏÇÑ ¸Þ½ÃÁö¸¦ º¸³»ÁÖ´Â ¸ÞÄ¿´ÏÁòÀ» °¡Áö°í ÀÖ´Ù. ¹Ý´ëÀÇ °³³äÀ¸·Î ¿ì¸®°¡ ¾îÇø®ÄÉÀ̼ǿ¡¼­ ÆÄÀÏÀ» »èÁ¦Çϰųª »ý¼ºÇßÀ» ¶§ À̸¦ À©µµ ½Ã½ºÅÛ¿¡ Å뺸ÇÒ ¼ö Àִµ¥ À̶§ »ç¿ëÇÏ´Â APIÀÎ SHChangeNotify´Â WIN32 SDK¿¡ ÀÚ¼¼ÇÏ°Ô ¼³¸íµÇ¾î ÀÖÁö¸¸ À©µµ ½©¿¡ º¯È­°¡ »ý±æ ¶§¸¶´Ù ³»°¡ ÁöÁ¤ÇÑ Æ¯Á¤ À©µµ¿¡ Å뺸 ¸Þ½ÃÁö¸¦ º¸³» ÁÖµµ·Ï ÇÏ°í ½ÍÀ» ¶§ »ç¿ëÇÏ´Â APIÀÎ SHChangeNotifyRegister, SHChangeNotifyDeregister´Â WIN32 SDK µµ¿ò¸»¿¡ ¼³¸íµÇ¾î ÀÖÁö ¾Ê´Ù. ÀÌ APIµéÀº ¹®¼­È­ µÇÁö ¾ÊÀº APIÀ̱⠶§¹®¿¡ DLLÀÌ ¾÷±×·¹ÀÌµå µÇ°Å³ª »èÁ¦µÇ¸é ÀÌ APIµéÀ» »ç¿ëÇÒ ¼ö ¾ø°Ô µÉ ¼öµµ ÀÖÁö¸¸ ÇöÀç Windows 95, Windows 98, Windows NT 4.0¿¡¼­´Â ¸ðµÎ »ç¿ëÇÒ ¼ö ÀÖÀ¸¹Ç·Î ÀÌ·± À©µµ ½Ã½ºÅÛÀÇ À̺¥Æ® ÅëÁö ±â´ÉÀ» ÄÞÆ÷³ÍÆ®·Î ±¸ÇöÇØ¼­ º¯È­°¡ »ý±æ ¶§ ¸¶´Ù À̺¥Æ®¸¦ ¹ß»ý½ÃŰ´Â ÄÞÆ÷³ÍÆ®¸¦ ¸¸µé¾î º¸ÀÚ.
shell32.dll¿¡¼­ µÎ ¹øÂ°·Î Á¤ÀǵǾî ÀÖ´Â ShChangeNotifyRegister ÇÔ¼öÀÇ ¿øÇüÀº ¾Æ·¡¿Í °°´Ù.

function SHChangeNotifyRegister(WindowHandle: HWND;
                                uFlags : UINT;
                                wEventId : LongInt;
                                uMsg : UINT;
                                cItems : DWORD;
                                Items : PPIDLStruct) : THandle; stdcall;


ù¹øÂ° ÀÎÀÚÀÎ WindowHandleÀº Å뺸 ¸Þ½ÃÁö¸¦ ¹ÞÀ» À©µµ¿¡ ´ëÇÑ ÇÚµéÀ» °¡¸®Å²´Ù. uFlags´Â À̺¥Æ®¸¦ ÇÊÅ͸µÇÏ´Â µ¥ »ç¿ëÇϸç wEventId´Â ¹ÞÀ» À̺¥Æ®¿¡ ´ëÇÑ ¸¶½ºÅ©¸¦ ³Ö¾î ÁØ´Ù. uMsg´Â À̺¥Æ®°¡ ¹ß»ýÇßÀ» ¶§ ¹ÞÀ» ¸Þ½ÃÁö¸¦ ÀÔ·ÂÇϴµ¥ º¸Åë »ç¿ëÀÚ ¸Þ½ÃÁö¸¦(WM_USER + n) Á¤ÀÇÇØ¼­ »ç¿ëÇÑ´Ù. ±×¸®°í Items ÀÎÀÚ´Â PIDLStructÇü ¹è¿­¿¡ ´ëÇÑ Æ÷ÀÎÅÍÀ̸ç cItems´Â Items ÀÎÀÚÀÇ ¹è¿­ °³¼ö¸¦ ³ªÅ¸³½´Ù. WEventID¿¡ ÁöÁ¤ÇÒ ¼ö ÀÖ´Â À̺¥Æ®ÀÇ Á¾·ù´Â SHChangeNotifyÀÇ µµ¿ò¸»À» º¸¸é ÀÚ¼¼ÇÏ°Ô ³ª¿Í ÀÖ´Ù.
SHChangeNotifyRegisterÀÇ ¹Ýȯ°ªÀº ÇÚµéÀ̸ç ÀÌ °ªÀº SHChangeNotifyDeregister¸¦ ÀÌ¿ëÇØ¼­ µî·ÏÀ» ÇØÁ¦ÇÒ ¶§ »ç¿ëÇÑ´Ù. shell32.dll¿¡¼­ ³× ¹øÂ°·Î Á¤ÀǵǾî ÀÖ´Â ShChangeNotifyDeregister ÇÔ¼öÀÇ ¿øÇüÀº ¾Æ·¡¿Í °°À¸¸ç ÀÎÀÚ´Â SHChangeNotifyRegister¿¡¼­ ¹ÝȯÇÑ ÇÚµéÀÌ´Ù.

function SHChangeNotifyDeregister(hNotify : THandle) : BOOL; stdcall;


ÇѰ¡Áö ÁÖÀÇÇÒ °ÍÀº SHChangeNotifyÀÇ µµ¿ò¸»¿¡ ³ªÅ¸³ª ÀÖ´Â ¸ðµç À̺¥Æ®°¡ ¼³¸íµÈ ´ë·Î µ¿ÀÛÇÏÁö ¾Ê´Â´Ù´Â °ÍÀÌ´Ù. ¿¹¸¦ µé¾î ÆÄÀÏÀÇ ¼Ó¼ºÀ» º¯°æÇϸé SHCNE_ATTRIBUTES À̺¥Æ®°¡ ¹ß»ýÇÑ´Ù°í µÇ¾î ÀÖÁö¸¸ ÀÌ À̺¥Æ®´Â ¹ß»ýÇÏÁö ¾Ê°í SHCNE_UPDATEITEM À̺¥Æ®¸¸ ¹ß»ýÇÑ´Ù. °³ÀÎÀûÀÎ »ý°¢ÀÌÁö¸¸ ¾Æ¸¶µµ ¿Ïº®ÇÏ°Ô ±¸ÇöµÇÁö ¾Ê¾Æ¼­ SHChangeNotifyRegister¿Í SHChangeNotifyDeregister¸¦ ¹®¼­È­ÇÏÁö ¾ÊÀº µí ½Í´Ù.
ÀÌ ÄÞÆ÷³ÍÆ®ÀÇ À̸§Àº TdpbShellNotify·Î ÇÏ°í ½Ã°¢ÀûÀÎ ±â´ÉÀÌ ÇÊ¿ä ¾øÀ¸¹Ç·Î TComponent¿¡¼­ »ó¼Ó ¹ÞÀÚ. ¿Ï¼ºµÈ ÄÞÆ÷³ÍÆ®ÀÇ ¼Ò½º ÄÚµå¿Í ¿¹Á¦ ÇÁ·Î±×·¥ µ¿ÀÛ È­¸éÀ» ¾Æ·¡¿¡ ³ªÅ¸³»¾ú´Ù.

±×¸² 2-12 ½© º¯È­ °¨Áö ÄÞÆ÷³ÍÆ® ¿¹Á¦ È­¸é




¸®½ºÆ® 2.5 dpbShellNotify.pas
unit dpbShellNotify;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  FileCtrl,
  ShellApi,
  ShlObj,
  ActiveX;

type
  TPIDLStruct = packed record
    pidlPath:      PItemIDList;
    bWatchSubtree: BOOL;
  end;
  PPIDLStruct = ^TPIDLStruct;

  TSHNotifyStruct = packed record
    PIDL1: PItemIDList;
    PIDL2: PItemIDList;
  end;
  PSHNotifyStruct = ^TSHNotifyStruct;

  TdpbNotifyDouble  = procedure(Sender: TObject;
                                OldPIDL: PItemIdList;
                                OldPath: TFileName;
                                NewPIDL: PItemIdList;
                                NewPath: TFileName) of object;

  TdpbNotifySingle  = procedure(Sender: TObject;
                                PIDL: PItemIdList;
                                Path: TFileName) of object;

  TdpbRootFolder =
  (
    drtCustomPath,
    drtDesktop,
    drtProgramFiles,
    drtControlPanel,
    drtPrinters,
    drtMyDocuments,
    drtFavorites,
    drtStartup,
    drtRecent,
    drtSendTo,
    drtRecycleBin,
    drtStartMenu,
    drtDesktopDirectory,
    drtDrives,
    drtNetwork,
    drtNethoodDirectory,
    drtFonts,
    drtTemplates,
    drtCommonStartMenu,
    drtCommonProgramFiles,
    drtCommonStartup,
    drtCommonDesktopDirectory,
    drtCommonAppData,
    drtCommonPrinters
  );

  TdpbShellNotify = class(TComponent)
  private
    { Private declarations }
    FActive : Boolean;
    FHandle : HWND;
    FSHNotifyHandle : THandle;
    FRootPIDL : PItemIDList;
    FRootFolder : TdpbRootFolder;

    FOnRename : TdpbNotifyDouble;
    FOnCreate : TdpbNotifySingle;
    FOnDelete : TdpbNotifySingle;
    FOnUpdate : TdpbNotifySingle;
    FOnAttributesChanged : TdpbNotifySingle;
    FOnMakeDir : TdpbNotifySingle;
    FOnRemoveDir : TdpbNotifySingle;
    FOnUpdateDir : TdpbNotifySingle;
    FOnRenameDir : TdpbNotifyDouble;
    FOnDriveRemoved : TdpbNotifySingle;
    FOnDriveAdded : TdpbNotifySingle;
    FCustomPath: string;

    procedure ProcessNotifyMessage(wEventID: Integer; SHNS: PSHNotifyStruct);
    procedure SetActive(const Value: Boolean);
    procedure SetRootFolder(const Value: TdpbRootFolder);
    procedure SetCustomPath(const Value: string);
  protected
    { Protected declarations }
    procedure WndProc(var Message : TMessage);
  public
    { Public declarations }
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
    procedure Loaded; override;
    procedure Register;
    procedure Deregister;
  published
    { Published declarations }
    property Active : Boolean
             read FActive
             write SetActive
             default False;

    property RootFolder : TdpbRootFolder
             read FRootFolder
             write SetRootFolder
             default drtDeskTop;

    property CustomPath : string
             read FCustomPath
             write SetCustomPath;

    property OnCreate : TdpbNotifySingle
             read FOnCreate
             write FOnCreate;

    property OnRename : TdpbNotifyDouble
             read FOnRename
             write FOnRename;

    property OnDelete : TdpbNotifySingle
             read FOnDelete
             write FOnDelete;

    property OnUpdate : TdpbNotifySingle
             read FOnUpdate
             write FOnUpdate;

    property OnAttributesChanged : TdpbNotifySingle
             read FOnAttributesChanged
             write FOnAttributesChanged;

    property OnMakeDir : TdpbNotifySingle
             read FOnMakeDir
             write FOnMakeDir;

    property OnRemoveDir : TdpbNotifySingle
             read FOnRemoveDir
             write FOnRemoveDir;

    property OnUpdateDir : TdpbNotifySingle
             read FOnUpdateDir
             write FOnUpdateDir;

    property OnRenameDir : TdpbNotifyDouble
             read FOnRenameDir
             write FOnRenameDir;

    property OnDriveRemoved : TdpbNotifySingle
             read FOnDriveRemoved
             write FOnDriveRemoved;

    property OnDriveAdded : TdpbNotifySingle
             read FOnDriveAdded
             write FOnDriveAdded;
  end;


const
  WM_SHELLNOTIFY = WM_USER + 1;

function SHChangeNotifyRegister(WindowHandle: HWND;
                                uFlags : UINT;
                                wEventId : LongInt;
                                uMsg : UINT;
                                cItems : DWORD;
                                Items : PPIDLStruct) : THandle; stdcall;

function SHChangeNotifyDeregister(hNotify : THandle) : BOOL; stdcall;
function ILCreateFromPath(Path: Pointer): PItemIDList; stdcall;
function GetPathFromPIDL(PIDL: PItemIDList): string; stdcall;
function GetPIDLFromPath(Path: string): PItemIDList; stdcall;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('DPB', [TdpbShellNotify]);
end;

const
  SHELL_DLL = 'Shell32.dll';

  { SHChangeNotifyRegisterÀÇ uFlags }
  SHCNF_ACCEPT_INTERRUPTS=0001;
  SHCNF_ACCEPT_NON_INTERRUPTS=0002;
  SHCNF_NO_PROXY=8000;


function SHChangeNotifyRegister;   external SHELL_DLL  Index 2;
function SHChangeNotifyDeregister; external SHELL_DLL  Index 4;
function ILCreateFromPath;         external SHELL_DLL  Index 157;

function  GetPathFromPIDL(PIDL: PItemIDList): string; stdcall;
var
  PathBuffer: Array[0..MAX_PATH] of Char;
begin
  Result := EmptyStr;
  if (PIDL = nil) then
    Exit;
  { PIDL¿¡¼­ °æ·Î¸¦ ±¸ÇÑ´Ù. }
  SHGetPathFromIDList(PIDL, PathBuffer);
  Result := StrPas(PathBuffer);
end;

function GetPIDLFromPath(Path: string): PItemIDList; stdcall;
var
  Buffer: Array[0..MAX_PATH] of WideChar;
begin
  if (SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT) then
  begin
    StringToWideChar(Path, Buffer, (High(Buffer) - Low(Buffer) + 1));
  end
  else begin
    StrPLCopy(PChar(@Buffer), Path, SizeOf(Buffer));
  end;
  Result := ILCreateFromPath(@Buffer);
end;

function RootFolderToSpecialFolder(Value : TdpbRootFolder) : Integer;
begin
  case Value of
    drtDesktop:                Result := CSIDL_DESKTOP;
    drtProgramFiles:           Result := CSIDL_PROGRAMS;
    drtControlPanel:           Result := CSIDL_CONTROLS;
    drtPrinters:               Result := CSIDL_PRINTERS;
    drtMyDocuments:            Result := CSIDL_PERSONAL;
    drtFavorites:              Result := CSIDL_FAVORITES;
    drtStartup:                Result := CSIDL_STARTUP;
    drtRecent:                 Result := CSIDL_RECENT;
    drtSendTo:                 Result := CSIDL_SENDTO;
    drtRecycleBin:             Result := CSIDL_BITBUCKET;
    drtStartMenu:              Result := CSIDL_STARTMENU;
    drtDesktopDirectory:       Result := CSIDL_DESKTOPDIRECTORY;
    drtDrives:                 Result := CSIDL_DRIVES;
    drtNetwork:                Result := CSIDL_NETWORK;
    drtNethoodDirectory:       Result := CSIDL_NETHOOD;
    drtFonts:                  Result := CSIDL_FONTS;
    drtTemplates:              Result := CSIDL_TEMPLATES;
    drtCommonStartMenu:        Result := CSIDL_COMMON_STARTMENU;
    drtCommonProgramFiles:     Result := CSIDL_COMMON_PROGRAMS;
    drtCommonStartup:          Result := CSIDL_COMMON_STARTUP;
    drtCommonDesktopDirectory: Result := CSIDL_COMMON_DESKTOPDIRECTORY;
    drtCommonAppData:          Result := CSIDL_APPDATA;
    drtCommonPrinters:         Result := CSIDL_PRINTHOOD;
    else                       Result := CSIDL_DESKTOP;
  end;
end;

{ TdpbShellNotify }

constructor TdpbShellNotify.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FSHNotifyHandle := INVALID_HANDLE_VALUE;
  FRootPIDL := nil;
  { À©µµ ÇÚµéÀ» °­Á¦·Î ÇÒ´çÇÑ´Ù. }
  FHandle := AllocateHWND(WndProc);
  FActive := False;
  FRootFolder := drtDeskTop;
end;

destructor TdpbShellNotify.Destroy;
begin
  { µî·ÏÀ» ÇØÁ¦ ÇÑ´Ù. }
  if FSHNotifyHandle <> INVALID_HANDLE_VALUE then
    Deregister;

  { À©µµ ÇÚµé ÇØÁ¦ }
  DeallocateHWnd(FHandle);
  inherited Destroy;
end;

{ ½© ÅëÁö ¸Þ½ÃÁö µî·Ï }
procedure TdpbShellNotify.Register;
var
  PS : TPIDLStruct;
begin
  if FSHNotifyHandle = INVALID_HANDLE_VALUE then
  begin
    if FRootFolder = artCustomPath then
    begin
      if (Length(FCustomPath) > 0) and DirectoryExists(FCustomPath) then
      begin
        FRootPIDL := GetPIDLFromPath(FCustomPath);
      end
      else
        SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, FRootPIDL);
    end
    else
    begin
      SHGetSpecialFolderLocation(0, RootFolderToSpecialFolder(FRootFolder), FRootPIDL);
    end;
    PS.pidlPath := FRootPIDL;
    PS.bWatchSubtree := True;

    FSHNotifyHandle := SHChangeNotifyRegister(FHandle,
                                  SHCNF_ACCEPT_INTERRUPTS or SHCNF_ACCEPT_NON_INTERRUPTS,
                                  SHCNE_ALLEVENTS,
                                  WM_SHELLNOTIFY,
                                  1, @PS);
  end;
end;

procedure TdpbShellNotify.Deregister;
begin
  if FSHNotifyHandle <> INVALID_HANDLE_VALUE then
  begin
    if SHChangeNotifyDeregister(FSHNotifyHandle) then
    begin
      FSHNotifyHandle := INVALID_HANDLE_VALUE;
      CoTaskMemFree(FRootPIDL);
      FRootPIDL := nil;
    end;
  end;
end;

procedure TdpbShellNotify.WndProc(var Message: TMessage);
begin
  with Message do
  begin
    if Msg = WM_SHELLNOTIFY then
    begin
      ProcessNotifyMessage(lParam, PSHNotifyStruct(wParam));
      Result := 1;
    end
    else
      Result := DefWindowProc(FHandle, Msg, wParam, lParam);
  end;
end;

procedure TdpbShellNOtify.ProcessNotifyMessage(wEventID : Longint;
   SHNS : PSHNotifyStruct);
var
  Path1 : TFileName;
  Path2 : TFileName;
begin
  Path1 := GetPathFromPIDL(SHNS.PIDL1);
  Path2 := GetPathFromPIDL(SHNS.PIDL2);
  case wEventID of
    SHCNE_RENAMEITEM   :
      if Assigned(FOnRename) then
        FOnRename(Self, SHNS.PIDL1, Path1, SHNS.PIDL2, Path2);
    SHCNE_CREATE       :
      if Assigned(FOnCreate) then
        FOnCreate(Self, SHNS.PIDL1, Path1);
    SHCNE_DELETE       :
      if Assigned(FOnDelete) then
        FOnDelete(Self, SHNS.PIDL1, Path1);
    SHCNE_UPDATEITEM   :
      if Assigned(FOnUpdate) then
        FOnUpdate(Self, SHNS.PIDL1, Path1);
    SHCNE_ATTRIBUTES   :
      if Assigned(FOnAttributesChanged) then
        FOnAttributesChanged(Self, SHNS.PIDL1, Path1);
    SHCNE_MKDIR        :
      if Assigned(FOnMakeDir) then
        FOnMakeDir(Self, SHNS.PIDL1, Path1);
    SHCNE_RMDIR        :
      if Assigned(FOnRemoveDir) then
        FOnRemoveDir(Self, SHNS.PIDL1, Path1);
    SHCNE_UPDATEDIR    :
      if Assigned(FOnUpdateDir) then
        FOnUpdateDir(Self, SHNS.PIDL1, Path1);
    SHCNE_RENAMEFOLDER :
      if Assigned(FOnRenameDir) then
        FOnRenameDir(Self, SHNS.PIDL1, Path1, SHNS.PIDL2, Path2);
    SHCNE_DRIVEREMOVED :
      if Assigned(FOnDriveRemoved) then
        FOnDriveRemoved(Self, SHNS.PIDL1, Path1);
    SHCNE_DRIVEADD     :
      if Assigned(FOnDriveAdded) then
        FOnDriveAdded(Self, SHNS.PIDL1, Path1);
  end;
end;

procedure TdpbShellNotify.Loaded;
begin
  inherited Loaded;
  { ÀÚµ¿ µî·Ï }
  if not (csDesigning in ComponentState) and FActive then
  begin
    Register;
  end;
end;

procedure TdpbShellNotify.SetActive(const Value: Boolean);
begin
  if FActive <> Value then
  begin
    FActive := Value;
    if not (csDesigning in ComponentState) then
    begin
      if FActive then Register
      else  Deregister;
    end;
  end;
end;

procedure TdpbShellNotify.SetRootFolder(const Value: TdpbRootFolder);
begin
  if FRootFolder <> Value then
  begin
    FRootFolder := Value;
    if not (csDesigning in ComponentState) and FActive then
    begin
      Deregister;
      Register;
    end;
  end;
end;

procedure TdpbShellNotify.SetCustomPath(const Value: string);
begin
  if FCustomPath <> Value then
  begin
    FCustomPath := Value;
    if FRootFolder = drtCustomPath then
    begin
      if not (csDesigning in ComponentState) and FActive then
      begin
        Deregister;
        Register;
      end;
    end;
  end;
end;

end.


TdpbShellNotify´Â ÀÚ½ÅÀÌ µî·ÏÇÑ À©µµ ¸Þ½ÃÁö¸¦ ¹Þ¾Æ¾ß ÇÑ´Ù. ±×·±µ¥ ÀÌÀü Àå¿¡¼­µµ ¾ê±âÇßÁö¸¸ TComponent´Â À©µµ ÇÚµéÀ» °¡Áö°í ÀÖÁö ¾Ê±â ¶§¹®¿¡ À©µµ ¸Þ½ÃÁö¸¦ ¹ÞÀ» ¼ö ¾ø´Ù. ±×·¡¼­ °­Á¦·Î À©µµ ÇÚµéÀ» ¸¸µé¾î ÁÖ¾î¾ß Çϴµ¥ ÀÌ ¶§ »ç¿ëÇÏ´Â ÇÔ¼ö°¡ Forms.pas¿¡ Á¤ÀÇµÈ AllocateHWnd ÀÌ´Ù. AllocateHWnd ÇÔ¼ö´Â ¸Þ½ÃÁö¸¦ ¹Þ¾Æ¼­ ó¸®ÇÒ À©µµ ÇÁ·Î½ÃÀú¸¦ ÀÎÀÚ·Î ¹Þ´Â´Ù. µû¶ó¼­ TWndMethod ÇüÀÇ À©µµ ÇÁ·Î½ÃÀú WndProcÀ» ¸¸µé°í À̸¦ AllocateHWnd ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§ ÀÎÀÚ·Î ³Ö¾î ÁÖ¸é ÀÌ ÇÁ·Î½ÃÀú¿¡¼­ ¸Þ½ÃÁö¸¦ ó¸®ÇÒ ¼ö ÀÖ´Ù. À©µµ ÇÚµéÀ» ¸ðµÎ »ç¿ëÇßÀ¸¸é ¹Ýµå½ÃDeallocateHWnd ÇÁ·Î½ÃÀú¸¦ ÀÌ¿ëÇØ¼­ ÇÚµéÀ» ÇØÁ¦ÇØ ÁÖ¾î¾ß ÇÑ´Ù. TdpbShellNotify´Â ÄÞÆ÷³ÍÆ®ÀÇ »ý¼ºÀÚ¿¡¼­ AllocateHWnd¸¦ È£ÃâÇØ¼­ À©µµ ÇÚµéÀ» »ý¼ºÇÏ°í ¼Ò¸êÀÚ¿¡¼­ DeallocateHWnd¸¦ È£ÃâÇϵµ·Ï Çß´Ù.
¼³°è ½Ã¿¡ Active ÇÁ·ÎÆÛƼ¸¦ True·Î ÇØ ³õÀ¸¸é ¾îÇø®ÄÉÀ̼ÇÀÌ ½ÇÇàµÉ ¶§ ÀÚµ¿À¸·Î ½©¿¡¼­ ¹ß»ýÇÑ º¯È­¸¦ °¨ÁöÇÒ ¼ö ÀÖµµ·Ï Çߴµ¥ À̸¦ ±¸ÇöÇϱâ À§Çؼ­ ¸ðµç ÇÁ·ÎÆÛƼ°¡ Æû ÆÄÀÏ¿¡¼­ ÀÐÇô Áø ÈÄ¿¡ È£ÃâµÇ´Â Loaded °¡»ó ¸Þ¼Òµå¸¦ ¿À¹ö¶óÀ̵å ÇØ¼­ Active ÇÁ·ÎÆÛƼ°¡ TrueÀ̰í ComponentState ÇÁ·ÎÆÛƼ¸¦ Á¶»çÇØ¼­ ÆûÀ» ¼³°è ÁßÀÌ ¾Æ´Ñ °æ¿ì¿¡ Register ÇÁ·Î½ÃÀú¸¦ È£ÃâÇϵµ·Ï Çß´Ù.
À̹ۿ¡ RootFolder ÇÁ·ÎÆÛƼ¿Í CustomPath ÇÁ·ÎÆÛƼ¸¦ ¸¸µé¾ú´Âµ¥ RootFolder ÇÁ·ÎÆÛƼ´Â TdpbShellNotify ÄÞÆ÷³ÍÆ®°¡ °¨½ÃÇÒ Æú´õÀÇ À§Ä¡¸¦ ÁöÁ¤ÇÑ´Ù. RootFolder ÇÁ·ÎÆÛƼÀÇ °ªÀÌ drtCustomPathÀ̸é CustomPath ÇÁ·ÎÆÛƼ¿¡ ÁöÁ¤µÈ µð·ºÅ丮¸¦ °¨½ÃÇϵµ·Ï Çß´Ù.


ÀúÀ۱ǿ¡ ´ëÇÑ °øÁö
ÀÌ ¹®¼­¿¡ Æ÷ÇÔµÈ ¸ðµç ±Û°ú ¼Ò½º ÄÚµå´Â ÀÛÀÚÀÎ Àú ±è¼ºµ¿ÀÇ ÁöÀû Àç»êÀÌÁö¸¸ ¹«´ÜÀ¸·Î ¹èÆ÷Çϰųª Ã¥À̳ª °­ÀÇ ±³ÀçµîÀ» À§ÇÑ º¹Á¦ µî ÀúÀÛ±ÇÀ» ÀúÇØÇÏ´Â ÇàÀ§¸¦ Á¦¿ÜÇϰí´Â ÀÚÀ¯·Ó°Ô »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.
¶ÇÇÑ ÀÌ ÆäÀÌÁö¿¡ ´ëÇÑ ¸µÅ©´Â ÀÚÀ¯·Ó°Ô ÇÒ ¼ö ÀÖÀ¸³ª Àü¹®À» ÀüÁ¦ÇÏ´Â ÀÏÀº Çã¿ëÇÏÁö ¾Ê½À´Ï´Ù.