시스템 디폴트 언어 ID - 한국어 : 1042


GetSystemDefaultLangID


시스템 기본 언어 - 한국어 : KOR


function GetSystemDefaultLang: string;

var

  szLang: array[0..5] of Char;

begin

  Result := '';

  GetLocaleInfo(GetSystemDefaultLCID, LOCALE_SABBREVLANGNAME,

    szLang, SizeOf(szLang) - 1);

  Result := szLang;

end;


 

로케일 얻기 - 한국 : 한국어(대한민국)


function CurrentLocale: string;

var

  ID: LangID;

  LanguageName: array[0..254] of Char;

begin

  {read current system locale}

  ID := GetSystemDefaultLangID;

  {convert an ID into text}

  VerLanguageName(ID, LanguageName, SizeOf(LanguageName));

  Result := LanguageName;

end;


설명은 따로 없습니다. 아래 코드를 참고하세요.


function BinToInt(const Bin: string): Integer;

var

  I, Len: Integer;

begin

  Result := 0;

  Len := Length(Bin);

  for i := Len downto 1 do

    if Bin[I] = '1' then

      Result := Result + (1 shl (Len - I));

end;


 

function HexToBin(const Hexadecimal: string): string;

const

  BCD: array[0..15] of string =

  ('0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111',

    '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111');

var

  I: integer;

begin

  for I := Length(Hexadecimal) downto 1 do

    Result := BCD[StrToInt('$' + Hexadecimal[I])] + Result;

end;


설명은 따로 없습니다. 아래 코드를 참고하세요.


const

  HexChars: array[0..15] of Char = ('0', '1', '2', '3', '4', '5',

                                    '6', '7', '8', '9', 'a', 'b',

                                    'c', 'd', 'e', 'f');


function IntToHex(Int: Int64; IntSize: Byte): string;

var

  n: Byte;

begin

  Result := '';

  for n := 0 to IntSize - 1 do

  begin

    Result := HexChars[Int and $F] + Result;

    Int := Int shr $4;

  end;

end;


 

function HexToInt(const Value: string): LongWord;

const

  HexStr: String = '0123456789abcdef';

var

  i: Word;

begin

  Result := 0;

  if Value = '' then Exit;

  for i := 1 to Length(Value) do

    Inc(Result, (Pos(Value[i], HexStr) - 1) shl ((Length(Value) - i) shl 2));

end;



특별한 설명은 없습니다. 아래 코드를 참고하세요.


type

  TByteArr = array of byte;


function ByteToString(const Value: TByteArr): String;

var

  I: integer;

  S : String;

  Letra: char;

begin

  S := '';

  for I := Length(Value)-1 downto 0 do begin

    letra := Chr(Value[I] + 48);

    S := letra + S;

  end;

  Result := S;

end;


 

function StrToByte(const Value: String): TByteArr;

var

  I: integer;

begin

  SetLength(Result, Length(Value));

  for I := 0 to Length(Value) - 1 do Result[I] := ord(Value[I + 1]) - 48;

end;


예전에는 자리비움 (키보드/마우스를 일정시간 사용하지 않고 있는 상태) 기능을 구현하기 위해 

훅 (HOOK) 을 이용한 DLL을 만들어 체크하였으나...


 

윈도우 2000 이후로 지원하는 GetLastInputInfo 덕분으로 여러모로 간단하게 자리비움 기능을 처리할 수 있다.


uses Windows;


class function GetSecondsIdle: DWORD;

var

  LII: TLastInputInfo;

begin

  LII.cbSize := SizeOf(TLastInputInfo);

  GetLastInputInfo(LII);

  Result := (GetTickCount - LII.dwTime) div 1000;

end;


이 함수를 이용해서 컴퓨터의 유휴시간을 초로 구해서 자리비움을 구현하자. 

(간단하게 1초짜리 타이머를 돌려서 유휴시간과 비교해가면서 체크하면 됨)

델파이 기본 웹브라우저 컴포넌트는 TWebBrowser인데. 이놈이 Internet Explorer를 맵핑해놓은거다.


기존에는 델파이로 응용프로그램을 구현할 때, 내부에 웹뷰가 필요하면 이 녀석을 사용했는데..

아무래도 표준도 잘 안지키고, 버전별로 표준 구현의 차이가 심하여.. Chrome 브라우저를 웹뷰로 사용해보기로 함.


검색을 해보니. Delphi Chromium Embedded (DCEF) 라는 놈이 있는데, 이게 DCEF 1, DCEF 3 이렇게 나눠져있더라는...

DCEF 1를 진행하다 개발이 중단된 거 같고, 그걸 포크해서 DCEF 3을 다시 개발한 거 같은데.. 잘은 모르겠고...

소스를 대략 보니 DCEF 3이 완성도가 더 있는 듯.. (찾아보니 DCEF 3은 multi-process용으로 재개발한 버전으로 보인다)


 

DCEF 1은 https://code.google.com/p/delphichromiumembedded/


DCEF 3 은 https://code.google.com/p/dcef3/ 

DCEF 3 은 위의 클론인 Github 사이트도 있음 (https://github.com/svn2github/dcef3)


데모도 있고 하지만, 실제로 많이 테스트를 해봐야지 개념을 익히게 되는 듯..

브라우저가 서로 다르니 당연하겠지만, TWebBrowser랑 처리 방식이 달라서.. 좀 헤매기도 함..


여튼, 로딩이나 랜더링 속도도 빠르고 표준 기술도 적용 잘되고 만족. 

크롬 브라우저가 설치안된 Windows에서도 구동이 되어야 하니, 관련된 정보를 다 담고 있는 관련 dll이 용량이 좀 됨

머.. 설치할때 한 번만 같이 배포하면 되니까 머 딱히 문제는 없음.


도움말이 도움이 큼.

https://code.google.com/p/chromiumembedded/wiki/GeneralUsage

https://code.google.com/p/chromiumembedded/wiki/JavaScriptIntegration

 

type

TObjectFromLResult = function(LRESULT: lResult; const IID: TIID;

WPARAM: wParam; out pObject): HRESULT; stdcall;


function GetIEFromHWND(WHandle: HWND; var IE: IWebbrowser2): HRESULT;

var

hInst: HWND;

lRes: Cardinal;

MSG: Integer;

pDoc: IHTMLDocument2;

ObjectFromLresult: TObjectFromLresult;

begin

hInst := LoadLibrary(‘Oleacc.dll’);

@ObjectFromLresult := GetProcAddress(hInst, ‘ObjectFromLresult’);

if @ObjectFromLresult <> nil then

begin

try

MSG := RegisterWindowMessage(‘WM_HTML_GETOBJECT’);

SendMessageTimeOut(WHandle, MSG, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes);

Result := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);

if Result = S_OK then

(pDoc.parentWindow as IServiceprovider).QueryService(IWebbrowserApp, IWebbrowser2, IE);

finally

FreeLibrary(hInst);

end;

end;

end;

델파이 7에서 SOAP 방식으로 닷넷서비스와 통신을 하는 프로그램을 만들었는데요.

비스타에서 에러가 나길래 뜯어보니.. SOAP 함수 호출시 Access violation 이 납니다.


비스타에서만 뭔가가 안될 경우엔 우선적으로 DEP 쪽을 확인해보는데.. 역시나 DEP 문제더군요.


DEP 가 비스타만의 문제는 아니지만 비스타에서는 기본적으로 모든 프로그램에 DEP 가 활성화되어있다보니 하드웨어가 DEP를 지원만 한다면 프로그램이 제대로 실행안되는 경우가 발생합니다. 외부 컴포넌트를 쓸 경우에도 그렇고..


결론적으로 델파이 7에 기본적으로 있는 Rio.pas 가 원인이었고.. 구글을 통해 해결책을 찾았습니다.


http://groups.google.com/group/borland.public.delphi.webservices.soap/browse_frm/thread/d986d9b0a1031506/21b1b8972e03afc9?q=delphi+soap+patch+rio.pas&rnum=1&hl=e


두군데를 고쳐주면 되구요. 적용해보니.. 문제없이 잘 돌아갑니다.


 

function TRIO.GenVTable(const IID: TGUID): Boolean; 에서


{ Allocate two blocks – one for the vtable itself, one for }

{ the thunks. }

GetMem(IntfTable, (Length(IntfMD.MDA) + NumEntriesInIInterface) * 4);

IntfTableP := @IntfTable;

GetMem(IntfStubs, (Length( IntfMD.MDA) + NumEntriesInIInterface) * StubSize );

// DEP 관련해서 문제가 있어서 여기서부터 추가

{ TODO -owilli -cpatch : windows xp NX patch }

{$IFDEF MSWINDOWS}

IntfStubs := Virtualalloc (Nil,(Length( IntfMD.MDA) + NumEntriesInIInterface) * StubSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);

{$ENDIF}

{$IFDEF LINUX}

GetMem(IntfStubs, (Length( IntfMD.MDA) + NumEntriesInIInterface) * StubSize);

{$ENDIF}

// 여기까지

{ Load the IUnknown vtable entries }

VTable := PPointer(IntfTable);

Crack.QIFn := _QIFromIntf;


destructor TRIO.Destroy; 에서


if IntfTable <> nil then

FreeMem(IntfTable);

// DEP 관련해서 문제가 있어서 여기서부터 추가

{ TODO -owilli -cpatch : windows xp NX patch }

if IntfStubs <> nil then

// FreeMem(IntfStubs);

{$IFDEF MSWINDOWS}

Virtualfree (IntfStubs,0,MEM_RELEASE);

{$ENDIF}

{$IFDEF LINUX}

FreeMem(IntfStubs);

{$ENDIF}

// 여기까지

if FContext <> nil then

FContext.Free;


 

보통 폴더 열때 아래처럼 사용을 합니다.

ShellExecute(Handle, ‘open’, PChar(‘C:\Data’), nil, nil, SW_SHOWNORMAL);

근데 파일 다운로드하고 폴더 열때 다운로드한 파일이 선택된 상태로 열려면 아래처럼 하시면 됩니다.

ShellExecute(Handle, ‘open’, ‘explorer.exe’, PChar(‘/select,”C:\Data\text.exe”‘), nil, SW_SHOWNORMAL);

explorer.exe 의 옵션 중에 /select 라는 게 있더군요.

근데 하나의 파일은 되는데.. 여러 파일이 선택된 상태로 여는 건 어떻게 하는지 궁금.. ^^

 

델파이에서 crontab의 cron 포맷으로 스케줄링할 수 있는 CRON Scheduler


http://www.cromis.net/blog/downloads/cron-scheduler/


cron 포맷에서 초까지 설정 가능


<Second> <Minute> <Hour> <Day_of_the_Month> <Month_of_the_Year> <Day_of_the_Week>

+ Recent posts