uses

  Winapi.ImageHlp, Winapi.Windows;


function GetDLLExports(const AFileName: AnsiString; AList: TStrings): Boolean;

var

  Image: LoadedImage;

  pExport: PImageExportDirectory;

  pNames: PDWORD;

  Dummy: DWORD;

  I: DWORD;

begin

  Result := MapAndLoad(PAnsiChar(AFileName), nil, @Image, True, True);

  if Result then begin

    try

      pExport := ImageDirectoryEntryToData(Image.MappedAddress, False, IMAGE_DIRECTORY_ENTRY_EXPORT, ULONG(Dummy));

      if pExport <> nil then begin

        pNames := ImageRvaToVa(Image.FileHeader, Image.MappedAddress, pExport^.AddressOfNames, Pointer(Dummy));

        for I := 0 to Pred(pExport^.NumberOfNames) do begin

          AList.Add(String(PAnsiChar(ImageRvaToVa(Image.FileHeader, Image.MappedAddress, pNames^, Pointer(Dummy)))));

          Inc(pNames);

        end;

      end else begin

        Result := False;

      end;

    finally

      UnMapAndLoad(@Image);

    end;

  end;

end;


문자열이 화면에 표시될때의 가로폭은 TCanvas.TextWidth 를 이용하여 확인된다.


1. 문자열이 원하는 길이보다 크면 문자열 뒤에 말줄임표 추가

2. 문자열이 원하는 길이보다 길지 않을 때까지, 말줄임표 앞 1글자를 삭제

3. 말줄임표 앞 1글자가 2바이트 문자의 앞(Lead) 문자일 경우 삭제


AnsiString __fastcall TextEllipsis(TCanvas *C, AnsiString V, int W, const AnsiString &P = "...")

{

for (C->TextWidth(V) > W? V += P: V; V.Length() > 0 && C->TextWidth(V) > W; V.Delete(V.Length() - P.Length(), 1));

if (ByteType(V, V.Length() - P.Length()) == mbLeadByte) {

V.Delete(V.Length() - P.Length(), 1);

}

return V;

}


'Windows > RAD Studio' 카테고리의 다른 글

DLL Export 함수 목록 가져오기  (0) 2015.10.07
[CB] Ole - InternetExplorer 띄우기  (0) 2015.09.17
프로세스 종료  (0) 2015.09.08
DLL 기본 주석 문구 해석  (0) 2015.05.13
[Del] TListBox HorizontalScrollBar 표시  (0) 2015.05.06

다른 속성과 함수는 ActiveX Control Test Container 같은 프로그램으로 확인하자.


#include <System.Win.Comobj.hpp>


Variant IE = System::Win::Comobj::CreateOleObject("InternetExplorer.Application");
IE.OleProcedure("Navigate2", WideString("http://google.com/"));
IE.OlePropertySet("ToolBar", false);
IE.OlePropertySet("AddressBar", true);
IE.OlePropertySet("Left", 0);
IE.OlePropertySet("Top", 0);
IE.OlePropertySet("Width", 640);
IE.OlePropertySet("Height", 480);
IE.OlePropertySet("Visible", true);
IE = Unassigned;


외부 프로세스를 강제로 종료하는 간단한 방법.

taskkill 커맨드를 이용하는 것이다.


::ShellExecute(NULL, L"runas", L"taskkill", String().sprintf(L"/pid %d /f", dwProcessId).c_str(), NULL, SW_HIDE);


이 코드를 실행하는 프로그램이 관리자 권한이 없을경우 "프로세스종료" 라는 내용의 권한 획득 창이 뜬다.


정상적인 종료를 시키려는 경우 복잡한 코드를 작성하고,

해당 프로그램의 동작은 신경쓰지 않고 무조건 죽이려 한다면 이렇게 하면 간단하다.


요약

1. export 된 함수 매개변수 또는 결과값으로 String 또는 String 을 포함하는 구조체/클래스 를 사용하는 경우

   DLL 과 DLL 을 사용하는 프로젝트에 MEMMGR.LIB 를 추가하라.

2. DLL 에서 export 된 TObject 에서 상속되지 않은 클래스를 new/delete 하는 경우 프로젝트에 MEMMGR.LIB 를 추가하라.

3. MEMMGR.LIB 를 추가하면 BORLNDMM.DLL 을 사용하게되므로 같이 배포해야 한다.

4. 이를 피하려면 "char*" 또는 ShortString 을 사용하라.

5. 동적 RTL 을 사용하는 경우에는 암시적으로 처리가 되므로 신경쓰지 않아도 된다.


원본


//   Important note about DLL memory management when your DLL uses the

//   static version of the RunTime Library:

//

//   If your DLL exports any functions that pass String objects (or structs/

//   classes containing nested Strings) as parameter or function results,

//   you will need to add the library MEMMGR.LIB to both the DLL project and

//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB

//   if any other projects which use the DLL will be performing new or delete

//   operations on any non-TObject-derived classes which are exported from the

//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling

//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,

//   the file BORLNDMM.DLL should be deployed along with your DLL.

//

//   To avoid using BORLNDMM.DLL, pass string information using "char *" or

//   ShortString parameters.

//

//   If your DLL uses the dynamic version of the RTL, you do not need to

//   explicitly add MEMMGR.LIB as this will be done implicitly for you


해석


//   정적 Runtime library 를 사용하는 DLL 메모리 관리에 관한 중요 사항:

//

//   DLL 이 매개변수 또는 반환 값으로 String 객체 (또는 String 을 포함하는

//   구조체/클래스) 를 전달하는 경우, MEMMGR.LIB 를 DLL 프로젝트와 DLL 을

//   사용하는 다른 프로젝트에 추가하여야 한다. 또한 DLL 을 사용하는 프로젝트가

//   DLL 에서 export 된 TObject 에서 상속받지 않은 클래스를 new 또는 delete

//   하는 경우 MEMMGR.LIB 를 추가해야 한다. MEMMGR.LIB 를 프로젝트에 추가하면

//   DLL 과 그것을 호출하는 EXE 의 메모리 관리자를 BORLNDMM.DLL 로 변경됩니다.

//   이경우, BORLNDMM.DLL 은 당신의 DLL 과 함께 배포해야 합니다.

//

//   BORLNDMM.DLL 사용을 피하기위해, "char *" 또는 ShortString 매개 변수로

//   문자열 정보를 전달하시오.

//

//   동적 RTL 을 사용할 경우, MEMMGR.LIB 가 암시적으로 추가되므로 이를

//   명시할 필요가 없다.


'Windows > RAD Studio' 카테고리의 다른 글

[CB] Ole - InternetExplorer 띄우기  (0) 2015.09.17
프로세스 종료  (0) 2015.09.08
[Del] TListBox HorizontalScrollBar 표시  (0) 2015.05.06
[Win32] 메모리 사용량 확인  (0) 2015.05.06
[C++, Win32] Thread safe FreeAndNil  (0) 2015.04.28



TListBox 를 사용하는 코드 전에 TListBox 의 type 을 재정의 해준다.


http://tinydew4.tistory.com/77 의 자동화 버전



uses

  Vcl.StdCtrls;


type

  TListBox = class(Vcl.StdCtrls.TListBox)

  private

    FMaxWidth: Integer;

  protected

    procedure WndProc(var Message: TMessage); override;

  end;


implementation


procedure TListBox.WndProc(var Message: TMessage);

var

  iTextWidth: Integer;


  procedure ItemAdded(AValue: PChar);

  begin

    iTextWidth := Canvas.TextWidth(AValue);

    if iTextWidth > FMaxWidth then begin

      InterlockedExchange(FMaxWidth, iTextWidth);

      Perform(LB_SETHORIZONTALEXTENT, FMaxWidth + 2, 0);

    end;

  end;

  procedure ItemDeleted(AItemIndex: Integer);

  var

    iMaxWidth: Integer;

    I: Integer;

  begin

    if (0 > AItemIndex) or (AItemIndex >= Items.Count) then

      Exit;


    iTextWidth := Canvas.TextWidth(Items.Strings[AItemIndex]);

    if iTextWidth < FMaxWidth then

      Exit;


    iMaxWidth := 0;

    for I := 0 to Pred(Items.Count) do begin

      if I <> AItemIndex then begin

        iTextWidth := Canvas.TextWidth(Items.Strings[I]);

        if iTextWidth > iMaxWidth then

          iMaxWidth := iTextWidth;

      end;

    end;


    if iMaxWidth <> FMaxWidth then begin

      InterlockedExchange(FMaxWidth, iMaxWidth);

      Perform(LB_SETHORIZONTALEXTENT, FMaxWidth + 2, 0);

    end;

  end;

begin

  if (Message.Msg = LB_ADDSTRING) or (Message.Msg = LB_INSERTSTRING) then begin

    ItemAdded(PChar(Message.LParam));

  end else if Message.Msg = LB_DELETESTRING then begin

    ItemDeleted(Message.WParam);

  end else if Message.Msg = WM_CREATE then begin

    InterlockedExchange(FMaxWidth, 0);

  end;


  inherited;

end;


GlobalMemoryStatusEx, TMemoryStatusEx


(GlobalMemoryStatus, TMemoryStatus - 4GB 의 한계가 있다.)


Win32 API 를 이용한 FreeAndNil 과 같은 역할을 하는 Thread-safe 한 함수이다.

하지만, Reference counting 은 없기에 여러 변수에서 참조하는 주소라면 문제가 될 수 있다.

(만능이 아니라는 말이다)


template<class T>

void __fastcall SafeFreeAndNil(T **Obj)

{

delete (T*)InterlockedExchangePointer(*Obj, NULL);

}


function GetBytesPerCluster(const ADrive: String): Int64;

var

  SectorsPerCluster: DWORD;

  BytesPerSector: DWORD;

  Dummy: DWORD;

begin

  if GetDiskFreeSpace(PChar(ADrive), SectorsPerCluster, BytesPerSector, Dummy, Dummy) = 0 then

    Exit(0);

  Result := SectorsPerCluster * BytesPerSector;

end;



$A              Determines whether data is aligned or packed

$Align          Determines whether data is aligned or packed

$AppType        Determines the application type : GUI or Console

$B              Whether to short cut and and or operations

$BoolEval       Whether to short cut and and or operations

$D              Determines whether application debug information is built

$DebugInfo      Determines whether application debug information is built

$Define         Defines a compiler directive symbol - as used by IfDef

$DefinitionInfo Determines whether application symbol information is built

$Else           Starts the alternate section of an IfDef or IfNDef

$EndIf          Terminates conditional code compilation

$ExtendedSyntax Controls some Pascal extension handling

$H              Treat string types as AnsiString or ShortString

$Hints          Determines whether Delphi shows compilation hints

$I              Allows code in an include file to be incorporated into a Unit

$IfDef          Executes code if a conditional symbol has been defined

$IfNDef         Executes code if a conditional symbol has not been defined

$IfOpt          Tests for the state of a Compiler directive

$Include        Allows code in an include file to be incorporated into a Unit

$IOChecks       When on, an IO operation error throws an exception

$L              Determines what application debug information is built

$LocalSymbols   Determines what application debug information is built

$LongStrings    Treat string types as AnsiString or ShortString

$MinEnumSize    Sets the minimum storage used to hold enumerated types

$O              Determines whether Delphi optimises code when compiling

$Optimization   Determines whether Delphi optimises code when compiling

$OverFlowChecks Determines whether Delphi checks integer and enum bounds

$Q              Determines whether Delphi checks integer and enum bounds

$R              Determines whether Delphi checks array bounds

$RangeChecks    Determines whether Delphi checks array bounds

$ReferenceInfo  Determines whether symbol reference information is built

$Resource       Defines a resource file to be included in the application linking

$UnDef          Undefines a compiler directive symbol - as used by IfDef

$Warnings       Determines whether Delphi shows compilation warnings

$X              Controls some Pascal extension handling

$Y              Determines whether application symbol information is built

$Z              Sets the minimum storage used to hold enumerated types



+ Recent posts