2009년 2월 19일 목요일

숫자 입력만 받아들이기


private void TextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!Char.IsDigit(e.KeyChar) && e.KeyChar != 8)
{
e.Handled = true;
}
}

TextBox에 KeyPress이벤트로 키 입력을 숫자키와 백스페이스로 제한한 코드다..
KeyChar값이 ASCII니까 8이 백스페이스.....

응용편....

Char.IsLetter(e.KeyChar) : 알파벳이라면 여기에 걸릴테지...
Char.IsSymbol(e.KeyChar) : 기호는 이걸로 거를테고...
Char.IsControl(e.KeyChar) : 제어 문자 거르고...
Char.IsPunctuation(e.KeyChar) : 구분 문자인지 체크..

숫자와 영문을 동시에 처리한다면 Char.IsLetterOrDigit()을 쓰는 방법도 있다..^^


크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Kuro™

2009년 2월 16일 월요일

텍스트 큐브에 입성~

우연한 기회에 초대장을 구해 텍스트 큐브로 입성~

이래서 비공개 블로그는 들어오는 것 만으로도 감동인가... T^T

므하하하~~

티스토리 데이터 모두 옮겼는데...;;;

우선은 양쪽 모두 포스팅 해야지 ㅠ.ㅠ

인터넷 없이 3일...

금요일 저녁부터 일요일까지 3일동안 인터넷 없는 밤을 보냈다..
이게 뭔일인지...
인터넷이 안되어 항의도 해볼까 했지만..
"오랜만에 좀 쉬어 보자" 라는 생각에 그냥 뒀다..
덕분에.. 잠도 푹~ 자고..
그동안 못본 영화랑 드라마도 좀 봐주고..
오늘 저녁엔 인터넷이 될라나 ㅡㅡ;

2009년 2월 11일 수요일

BestCrypt Traveller + Loader

단일 파일로 만들어진 파일 암호화 프로그램.

단일 파일 파일 구성, 간편한 셋팅 등으로 손쉽게 암호화된 컨테이너 파일을 생성할 수 있다.

### 준비물 ###
1. BestCrypt Traveller - 개인 사용자에게는 무료로 배포된다. 링크를 이용해 다운로드 받기를...
2. BestCrypt Loader - BCTraveller의 귀찮은 실행 문제를 해결해 주는 로더

### 사용 방법 ###

1. BestCrypt Traveller와 BestCrypt Loader를 다운로드 받는다.
2. BestCrypt Loader의 압축을 해제하여 적당한 디렉토리로 옮긴다.
3. 1에서 다운받은 BestCrypt Traveller를 2와 같은 디렉토리로 이동한다.
    다음과 같은 형태로 파일이 저장되어 있으면 OK.


4. BCTraveller Loader.exe를 실행한다.

### 컨테이너 파일 만들기 ###

1. 트레이 아이콘에서 BestCrypt를 클릭하고 "Create Ne Container"를 선택한다.

2. 저장할 파일 이름, 파일 저장 위치, 파일 사이즈 등의 속성을 설정한다.
주의 할 점은 파일 이름을 쓸 때에 확장자를 ".jbc"로 기입해 줘야 하며, 파일 저장 위치를 실행파일이 있는 하위의 Data 폴더에 저장하여야 한다. "Format now"를 선택하면, 컨테이너 파일이 생성되어 마운트 된 후 바로 드라이브 포멧 화면이 나타고, 포멧 후 바로 사용이 가능하다.

3. Create 버튼을 누르면 마운트 할때 사용할 비밀번호 입력화면이 나타난다.

4. 비밀 번호 입력 후 나타는 화면에서 마우스를 마구 움직이거나 키보드를 마구 두드려서 암호화 시드를 생성한다.
(OK 버튼이 활성화 될 때까지 가능한한 마구 두들기자.. ^^)

5. 드디어 컨테이너가 마운트 되고 포멧 화면이 나타났다.
6. 이제 포멧 후 이동식 디스크로 사용하면 된다. ^^

마운트 이후 트레이 메뉴의 변화 모습

### setting.ini 설정 ###

Data폴더 안에 있는 setting.ini 파일을 이용해 마운트할 파일을 지정하거나 드라이브명을 지정하여 사용할 수 있다.
setting.ini 파일이 없을 경우 BCTraveller Loader.exe를 실행하면 자동으로 생성되며, 이때 생성되는 항목은 Use와 Count 2개 항목이 '0' 값으로 설정된다.

아래는 ini 항목 설정 방법이다.
[Default]
Use : 기본값은 0으로 설정되어 있으며, 값이 0일 경우 setting.ini를 사용하지 않고 Data 폴더 안의 모든 jbc 파일을 HDD 이후 비어있는 드라이브명 부터 순서대로 마운트 한다. 1로 설정되어 있을 경우 [Container] 컬럼의 설정에 따라 동작한다.

[Container]
Count : 마운트할 컨테이너 개수를 지정한다. 0일 경우 컨테이너를 마운트 하지 않고 실행된다.
Container1 : 마운트될 컨테이너 파일 명을 지정한다.
Drive1 : 드라이브명을 고정하여 사용하고자 할 경우 입력한다. 비어있을 경우 순서대로 할당 받는다. (h: 형태로 기입)
Count 에 입력한 숫자 만큼 Container 및 Drive를 작성하여 주면 된다.
예를 들어 Count=2 로 설정하였을 경우

Count=2
Container1=MyDisk.jbc
Drive1=
Container2=Mydisk2.jbc
Drive2=y:

위와 같이 등록하면 됨.

BCTraveller Loader.exe가 실행되어 있는 상태에서 다시 실행하면 프로그램을 종료 시킬지 확인 후 종료한다. 이 때 마운트 되어있는 모든 컨테이너들을 마운트 해제하고 종료한다.(강제 종료)


----------- Cut Here 2009.02.11 ----------------------------------------------------------------------------------
로더 소스 일부를 수정했습니다. 여러 jbc파일을 마운트 할 때 마운트 중에 오류가 발생하는 경우가 있어.. Best Crypt에서 패스워드 창이 나타날때까지 WinWait함수로 기다리도록 수정했습니다.(딜레이 시간 설정 3초 - 3초정도면 넉넉할 듯 하더군요..)

스플래시 이미지 적용해 봤습니다.

----------- Cut Here 2009.02.13 ----------------------------------------------------------------------------------
스플래시 이미지 적용을 INI 설정으로 변경합니다.
INI 파일에서 [Default] 아래에 Splash=1로 값을 주면 됩니다.
설정값이 1일 경우 스플래시 이미지가 나타나며, 0일 경우에는 이미지 없이 바로 시작합니다.

2009년 2월 9일 월요일

C#으로 본 자료운용 구조[DFS와 BFS 비교]

얼마전 파일 검색 함수를 작성해 보면서 탐색 방법에 대한 고찰을 하게 되었다.

폴더에 대한 검색..

서브 폴더를 포함한 검색을 하며 검색되는 속도에 의해 얼마나 느려 질 수 있는지...

처음 사용하던 탐색 방법은 DFS(Depth First Search - 깊이 우선 방식)으로 Stack 구조의 재귀함수를 사용하는 방법이다.

아래는 C#으로 만들어본 DFS 방식의 파일 검색 함수이다.

private List DirSearch(string sDir, string extName)
{
    List tmpList = new List();

    try
    {
        foreach (string f in Directory.GetFiles(sDir, extName))
            tmpList.Add(f);
        foreach (string d in Directory.GetDirectories(sDir))
        {
            tmpList.AddRange(DirSearch(d, extName).ToArray());
        }
    }
    catch (Exception excpt)
    {
        MessageBox.Show(excpt.Message);
        //return tmpList;
    }

    return tmpList;
}


자주 다니는 사이트에서 BFS(Breadth First Search - 너비 우선 방식)을 알게되어 이를 운용해 봤는데 확실히 이 방법이

빠른 속도를 보인다. 다만.. 저장공간 사용량이 DFS에 비해 많다는 것...

하지만 요즘 PC들이 메모리가 좀 많은가... 많이 쓴다고 해봤자 메모리양에 비하면 새발의 피지... ㅎㅎ

아래는 BFS 방식의 파일 검색 함수 예제이다.

private List DirSearch(string sDir, string extName)
{
	List tmpDir = new List();
	List fileList = new List();

	int head = 0, tail = 0;
	tmpDir.Add(sDir);
	tail++;

	while (head != tail)
	{
		try
		{
			foreach (string d in Directory.GetDirectories(tmpDir[head]))
			{
				tmpDir.Add(d);
				tail++;
			}
			
			foreach (string f in Directory.GetFiles(tmpDir[head++], extName))
				fileList.Add(f);
		}
		catch (Exception excpt)
		{
			MessageBox.Show(excpt.Message);
			//return tmpList;
		}
	}
	return fileList;
}


좀.. 당황스러운건... C#으로 두 함수를 만들어 비교해 봤지만...

시간 차이가 거의 없다는 것... ㅡ_ㅢ;;;

나 실패한건가 T^T

2009년 2월 7일 토요일

스마트 클라이언트 만들기 첫 경험........

항상 인스톨쉴드 형태로 배포하고 사용하다 처음으로 스마트 클라이언트로 프로그램을 배포하는 경험을 했다..
고객측에서 웹페이지에 링크를 해달라는 요청....

무슨소린가 하고 다른 프로젝트 쪽에 확인해보니...
ClickOnce로 만들어 달라는 것이군...;;

두 시간 동안 자료 뒤지고.. 간단하게 웹서버 만들어서 무작정 따라해봤으나 ㅡㅡ;
DLL들 설치나... 게시할때 SSL 사용여부 등에 따라 ㅡㅡ;
아우.. ㅡ_ㅢ;;;
하루 날렸다 ㅡㅡ;

그나마 다행히 ClickOnce가 어떻게 돌아가는지는 이해했으니...;;;
안그럼..
 캐안습이었겠지 ㅡㅡ;

MS 스마트 클라이언트 아파치에서 실행 문제 해결

Clickonce로 배포한 프로그램이 아파치에서 실행을하면 xml태그가 표시되는 경우가 있다.

이 때는 프로그램이 게시되어 있는 폴더에 ".htaccess"라는 파일을 생성하고,
(이미 있다면 파일 하단에 추가)

아래 내용을 추가하여 저장합니다.

AddType application/x-ms-application application
AddType application/x-ms-manifest manifest
AddType application/octet-stream deploy

아파치를 재시작하고 다시 접속해 보면....
성공!!!

프로그램 중복 실행 방지 v2

static void Main()
{
    System.Diagnostics.Process[] myProc 
        = System.Diagnostics.Process.GetProcessesByName(Application.ProductName);
    if(myProc.Length < 2)
        Application.Run(new Form1());
   else
   {
        MessageBox.Show("이미 실행중입니다");
        Application.Exit();
   }
}

프로세스상에 실행된 프로그램으로 확인하는 방법

컴퓨터 관련 eBook 구할때...

영문이라 머리아프긴 하지만..
쓸만한 책들이 꾀 있는듯 해서 종종 들르는 사이트..

http://www.ebooksdownloadfree.com/

2009년 2월 5일 목요일

하위 폴더를 포함한 폴더 및 파일 검색 스크립트

FileSearch.au3#include <Array.au3>

#cs ----------------------------------------------------------------------------

  프로그램 이름 : FileSearch
  파일          : FileSearch.au3
  Autoit버전    : 3.3.0.0
  함수          : _FileSearch($sPath[, $sExt[, $iFlag]])
  설명          : 하위 폴더를 포함하여 폴더 및 파일 검색
                 $sPath - 파일 찾기 경로(지정하지 않을 경우 작업 폴더를 기본으로 함)
                 $sExt - 찾고자 하는 필터(기본값 '*')
                 $iFlag - 찾기 옵션
                    $iFlag = 0 폴더와 파일 모두 검색(기본값)
                    $iFlag = 1 파일만 검색
                    $iFlag = 2 폴더만 검색
  저자         : Kuro™
  연락처        : kuro78@gmil.com, http://kuroz.tistory.com
  환경          : WInXP SP3(윈도우NT기반)
  수정          : 2009.02.04 - 최초 작성

#ce ----------------------------------------------------------------------------

Func _FileSearch($sPath = '', $sExt = '*', $iFlag = 0)
    Local $aResult[1], $aPath[1]
    Local $iHead = 1, $iTail = 1, $iCount = 0
    Local $hSearch
   
    If $sPath = '' Then $sPath = @WorkingDir
    If StringRight($sPath, 1) = '\' Then $sPath = StringTrimRight($sPath, 1)
   
    _ArrayAdd($aPath, $sPath)
    $iTail += 1
   
    while $iHead <> $iTail
        Local $sTmp, $sTmpPath
        $sTmpPath = $aPath[$iHead] & '\'
       
        $hSearch = FileFindFirstFile($sTmpPath&$sExt)
        If @error <> -1 Then
            
            $iHead += 1
           
            Do
                $sTmp = FileFindNextFile($hSearch)
                If @error Then
                    FileClose($hSearch)
                    ExitLoop
                EndIf
               
                If $sTmp = '.' Or $sTmp = '..' Then ContinueLoop
               
                If StringInStr(FileGetAttrib($sTmpPath & $sTmp), 'D') Then
                    _ArrayAdd($aPath, $sTmpPath & $sTmp)
                    
                    If $iFlag <> 1 Then $iCount = _ArrayAdd($aResult, $sTmpPath & $sTmp)
                   
                    $iTail += 1
                    ContinueLoop
                EndIf
               
                If $iFlag <> 2 Then $iCount = _ArrayAdd($aResult, $sTmpPath & $sTmp)
            Until 0
        EndIf
    WEnd
   
    $aResult[0] = $iCount

    Return $aResult
EndFunc


최종 버전... 처음엔 재귀함수 형태로 파일 검색 로직을 만들었다가 좌절했던...
bfs 방식으로 검색하도록 수정 후 확실히 속도는 많이 올라갔음...

약 4000개 파일 2000개 폴더 검색하는데 평균 45초 정도 걸린다...;;

아래는 처음에 작성했던 소스.....

재귀함수는 저하늘에 별에게나 줘버려 ㅡ_ㅢ;;


#include-once
#include <Array.au3>


Func _FileSearch($sParam, $iSub = 0, $iDirInc = 0)
    Local $hSearch, $aList[1], $aDirs[1], $sPath, $sExt
    
    $sPath = StringLeft($sParam, StringInStr($sParam, '\', 0, -1))
    If $sPath = '' Then $sPath = @WorkingDir & '\'
    $sExt = StringTrimLeft($sParam, StringInStr($sParam, '\', 0, -1))
    If $sExt = '' Then $sExt = '*.*'
    
    $hSearch = FileFindFirstFile($sPath & $sExt)
    If @error <> -1 Then
        Local $sFile, $iCount
        Do
            $sFile = FileFindNextFile($hSearch)
            If @error Then
                FileClose($hSearch)
                ExitLoop
            EndIf
            If $sFile = '.' Or $sFile = '..' Then ContinueLoop
            
            If StringInStr(FileGetAttrib($sPath & $sFile), 'D') Then
                $iCnt = _ArrayAdd($aDirs, $sPath & $sFile)
                $aDirs[0] = $iCnt
                If Not $iDirInc Then ContinueLoop
            EndIf
            $iCount = _ArrayAdd($aList, $sPath & $sFile)
        until 0
        $aList[0] = $iCount
    EndIf
    
    If $iSub Then
        Local $aTmp
        For $i = 1 to $aDirs[0]
            $aTmp = _FileSearch($aDirs[$i] & '\' & $sExt, $iSub, $iDirInc)
            For $j = 1 to $aTmp[0]
                _ArrayAdd($aList, $aTmp[$j])
            Next
            $aList[0] += $aTmp[0]
        Next
    EndIf
    
    Return $aList
EndFunc




2009년 2월 4일 수요일

프로그램이 재부팅 후 한 번만 자동실행이 필요할때....

레지스트리의 다음 항목에 프로그램을 등록하면 컴퓨터가 재부팅 된 후 단 한 번만 자동 실행됩니다.
정상 실행되면, 레지스트리에서 자동으로 삭제됩니다.

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce

2009년 2월 3일 화요일

Splash 이미지 적용 예제

SplashImageOn("Splash", @ScriptDir & "\Data\splash.jpg", 300, 200, @DesktopWidth, @DesktopHeight, 1)  
WinSetTrans("Splash","",1)  
WinMove("Splash","", @DesktopWidth/2-300/2, @DesktopHeight/2-200/2)  
For $trans=0 to 255
WinSetTrans("Splash","",$trans)  
$trans+=1
Sleep(5)  
Next
Sleep(250)  
For $trans=255 to 0 Step -1
$trans-=1
WinSetTrans("Splash","",$trans)  
Sleep(5)  
Next
SplashOff()  

스플래시 이미지가 나타났다 사라지는 방법의 예제...
런처 만들때 써먹어야지 ^^;

SMemo Portable Loader + SMemo ver.1.7.1

SMemo 1.7.1 버전 입니다.
개인/기업에 관계없이 아무런 제한 없이 사용 가능한 메모장 프로그램입니다.


위 그림처럼 간단한 메모부터 스크린샷 까지 찍을 수 있는 다양한 기능의 메모장 기능과 알람, 달력, 시계 등의 기능을 가지고 있으며, 사실 로더 프로그램 없이도 포터블화가 가능합니다.

위 설정 화면의 무설치 버전 부분에 체크해 두면 설정을 xml파일로 저장해 주기 때문에 무설치로 사용 가능합니다.
다만.. 레지스트리 HKCU\SoftWare\SMemo Program 키에 일부 정보가 남게되고, 간혹 메모를 접어 놓았을 때 세부내용이 보이지 않는 경우가 있습니다. 물론 접어 놓은 메모를 펼치면 내용이 제대로 표시됩니다.

이것때문에.. 포터블 로더를 만들어봤습니다.

SMemo 설치 파일과 로더를 함께 올립니다.
로더를 사용하고자 할 경우 설치파일을 이용해 설치한 후 설치 폴더 내의 파일과 디렉토리를 모두 로더의 App 폴더에 복사해 넣거나, UniExtract를 이용해 설치파일을 풀어서 나온 것들을 App 폴더에 복사해 넣어 주면 됩니다.





Syntax Highlighter 적용

또 다시 Blue'nLIVE님의 도움을 블로그 글에 도움을 받아 Syntax Highlighter를 적용했다.
관련글: 블로그팁 : Code highlighter 더 쉽게 사용하기

또한 AutoIt 적용을 위해 dis1hades2님의 글에서도 역시 도움을 받아 적용에 성공 ^^
관련글: Autoit Syntax script for Google Code Syntax Highlighter

두 블로그의 파일을 다운로드 받아 먼저 업로드~~

다음 아래 내용을 skin.html의 태그 위에 추가한다.















이제 Code Highlighter 사용이 가능해 졌다~~ 우어 ㅠ.ㅠ
실제 사용할 때에는... css를 예로 들면 코드를 작성한 후 HTML모드로 변경하여
<pre name="code" class="css">를 코드 앞에 붙이고, 코드 뒤에 </pre>를 붙여주면 된다.

AutoIt의 경우 자신이 쓰는 AutoIt의 Function, Keyword, UDFs 목록으로 업데이트 하고자할 경우
function list.au3 파일의 $keywordfile 변수의 값을 자신의 Site4AutoIt이 설치된 경로로 변경해 준 후
이를 실행하면 3개의 텍스트 파일이 생성된다.
이들 파일의 내용을 shBrushAutoIt.js 파일에 각 명칭에 맞는 항목에 복사해 넣어 준 후 업로드하면 OK.

AutoIt의 경우 Site Editer에서 HTML로 내보내기하여 이를 복사해 넣는 방법을 많이 쓰고 있는데...
다른 언어들의 글을 작성하면서 Code Highlighter가 필요해 졌다...

2009년 2월 2일 월요일

[펌] 모달리스 다이얼로그 Enter, ESC 키 무시 방법과 소멸 방법

C#으로 ESC키 무시 방법을 찾는데 왜 찾는 녀석은 안나오고... C++에서의 방법들만 나오는지 ㅡ_ㅢ;;
에효.. 암튼... 언제든 쓸모가 있을 듯 하니... 한번 옮겨놔 보련다.....


1. Enter, ESC 키 무시 방법

모달리스 다이얼로그를 만들고 이 ESC,ENTER 키를 입력하면 다이얼로그가 사라지게 됩니다. 그렇다고 꼭 이 두 키를 무시해야 한다는 건 아니고 경우에 따라 무시를 해도 되고 다른 동작을 하게해도 됩니다. 이는 개발자 마음!!
모달리스 다이얼로그 클래스에서 PreTranslateMessage()를 아래와 같이 오버라이딩 해주면 됩니다.


/*
     ESC, Enter key를 무시한다.
*/
BOOL CProcessADlg::PreTranslateMessage(MSG* pMsg)
{
    // TODO: Add your specialized code here and/or call the base class
    switch(pMsg->message)
    {
    case WM_KEYDOWN:
        {
            switch(pMsg->wParam)
            {
            case VK_ESCAPE:
            case VK_RETURN:
                return TRUE;
            }
        }
    }
    return CDialog::PreTranslateMessage(pMsg);
}


2. 소멸 방법

모 달리스 다이얼로그를 소멸하려면 두 가지 측면에서 생각해야 합니다. 하나는 모달리스 다이얼로그를 생성하는 부모 윈도우 객체이고 하나는 모달리스 다이얼로그 자신입니다.  부모 윈도우 객체에서는 모달리스 다이얼로그를 생성할 때 모달리스 다이얼로그 객체 변수를 정한 후 메모리 할당을 하고 Create()함수를 호출하여 생성하게 됩니다. 그렇다면 모달리스 다이얼로그가 파괴 될 때 부모 윈도우가 이를 알 수 있어야 메모리 해제를 제대로 해 줄 수 있습니다. 제가 사용한 방식은 모달리스 다이얼로그 객체에서 자기 자신의 메모리를 해제하고 부모 윈도우에서는 모달리스 다이얼로그 객체변수에 NULL 포인터를 전달하는 방식을 사용했습니다. 이렇게 하기 위해서 모달리스 다이얼로그의 PostNcDestroy()가 호출 되는 시점에서 부모 윈도우에게 사용자 정의 메시지(저는 WM_DESTROY_DLG라고 정했습니다.)를 하나 정해서 SendMessage함수를 통해서 메시지를 전달해 주고 부모 윈도우에서는 이 메시지를 처리합니다. 그리고 모달리스 다이얼로그에서 자기 자신의 메모리를 해제 합니다. 이 과정에 대해서는 예제 소스를 함께 첩부해 놓았습니다. 말로 잘 설명해보려고 했는데 글 재주가 없어서;;


※ 위 글에 대한 잘못된 부분이나 궁금하신 부분에 대한 피드백은 언제나 환영입니다 ~ 물론, 퍼가신다면 영광이구요. 우리나라의 모든 개발자 분들께서 바쁘시지만 서로 자신의 귀중한 경험과 지식을 공유해서 함께 발전해 나갈 수 있었으면 합니다 ^^

Dialog.zip


출처: greenfrog님의 블로그 - Programmer greenfrog!!

AutoIt에서 멀티 프로세싱 구현

AutoIt으로 요즘 구상중인 프로젝트를 구현하려고 보니 멀티 스레드의 필요성이 팍팍~

어떤 방법으로 구현이 가능할까 고민하던 중 떡~하니 보여진 UO의 글 덕분에 길이 열렸다... 지화자~~

CoProc.au3 UDF를 이용하면 멀티 프로세싱을 구현할 수 있다. 뭐.. 두개든 세개든 돌아간다는 것에 도낀개낀 해보자.. ㅋㅋㅋ

다음은 CoProc UDF에 포함된 함수 리스트이다.


test.au3_CoProc([$sFunction],[$vParameter])
    ;Starts another Process and Calls $sFunc, Returns PID
_SuperGlobalSet($sName,[$vValue],[$sRegistryBase])
    ;Sets or Deletes a Superglobal Variable
_SuperGlobalGet($sName,[$fOption],[$sRegistryBase])
    ;Returns the Value of a Superglobal Variable
_ProcSuspend($vProcess)
    ;Suspends all Threads in $vProcess (PID or Name)
_ProcResume($vProcess)
    ;Resumes all Threads in $vProcess (PID or Name)
_ProcessGetWinList($vProcess, $sTitle = Default, $iOption = 0)
    ;Enumerates Windows of a Process
_CoProcReciver([$sFunction = ""])
    ;Register/Unregister Reciver Function
_CoProcSend($vProcess, $vParameter,[$iTimeout = 500],[$fAbortIfHung = True])
    ;Send Message to Process
_ConsoleForward($iPid1, [$iPid2], [$iPid3], [$iPidn])
_ProcessEmptyWorkingSet($vPid = @AutoItPID,[$hDll_psapi],[$hDll_kernel32])
    ;Removes as many pages as possible from the working set of the specified process.
_DuplicateHandle($dwSourcePid, $hSourceHandle, $dwTargetPid = @AutoItPID, $fCloseSource = False)
    ;Returns a Duplicate handle
_CloseHandle($hAny)
    ;Close a Handle



예제 파일도 포함되어 있지만.. 멀티 프로세스로 잘 돌아가는지 좀더 확실히 확인해 보고싶어 _CoProc()함수를
아래와 같이 수정해 봤다.


test.au3#NoTrayIcon
#include "CoProc.au3"

$iProc2Pid = _CoProc("_proc2", "notepad.exe")
$iProc3Pid = _CoProc("_Proc2", "regedit.exe")
sleep(500)

Func _Proc2($vParam)
    runwait($vParam)
    MsgBox(0, '', 'close')
EndFunc   ;==>_Proc2


AutoIt 3.3.0.0 버전을 사용한다면 RunErrorsFatal 예약어가 삭제되었으므로
아래와 같이 CoPorc.au3파일을 수정할 필요가 있다.


Func _CoProc($sFunction = Default, $vParameter = Default)
    Local $iPid, $iOldRunErrorsFatal
    If IsKeyword($sFunction) Or $sFunction = "" Then $sFunction = "__CoProcDummy"
    ;$iOldRunErrorsFatal = Opt("RunErrorsFatal", 0)
    EnvSet("CoProc", "0x" & Hex(StringToBinary ($sFunction)))
    EnvSet("CoProcParent", @AutoItPID)
    If Not IsKeyword($vParameter) Then
        EnvSet("CoProcParameterPresent", "True")
        EnvSet("CoProcParameter", StringToBinary ($vParameter))
    Else
        EnvSet("CoProcParameterPresent", "False")
    EndIf
    If @Compiled Then
        $iPid = Run(FileGetShortName(@AutoItExe), @WorkingDir, @SW_HIDE, 1 + 2 + 4)
    Else
        $iPid = Run(FileGetShortName(@AutoItExe) & ' "' & @ScriptFullPath & '"', @WorkingDir, @SW_HIDE, 1 + 2 + 4)
    EndIf
    If @error Then SetError(1)
    ;Opt("RunErrorsFatal", $iOldRunErrorsFatal)
    Return $iPid
EndFunc   ;==>_CoProc



이제 겨우 _CoProc()함수 익히고, _SuperGlobalGet(), _SuperGlobalSet(), _ProcessGetWinList()함수 정도 이해했다..;;
아직 갈길이 너무 멀어 ㅠ.ㅠ