레이블이 인 게시물을 표시합니다. 모든 게시물 표시
레이블이 인 게시물을 표시합니다. 모든 게시물 표시

2019년 4월 1일 월요일

Wemos D1 mini ESP8266 WiFiClient NonBlocking

Wemos D1 mini : 저렴한 가격 + 작은 크기 + WiFi + Arduino

WiFi 로 Server 에 접속할때 connect 명령에서 최대 5초간 멈춤이 발생한다.
NonBlocking, Asynchronous connect 명령을 만들었다.

해결방법:

esp8266 라이브러리 폴더를 찾는다.
C:/Users/UserID/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src

1. WiFiClient.h 59line 에 추가.
    int connectAsync(const char* host, uint16_t port);
    int connectCheck();

2. WiFiClient.cpp 182line 에 추가.
    int WiFiClient::connectAsync(const char* host, uint16_t port) {
        IPAddress ip;
        if (!WiFi.hostByName(host, ip, _timeout)) return 0;
        if (_client) {
            stop();
            _client->unref();
            _client = nullptr;
        }
    #if LWIP_VERSION_MAJOR == 1
        netif* interface = ip_route(ip);
        if (!interface) {
            DEBUGV("no route to host\r\n");
            return 0;
        }
    #endif
        tcp_pcb* pcb = tcp_new();
        if (!pcb) return 0;
        if (_localPort > 0)  pcb->local_port = _localPort++;
        _client = new ClientContext(pcb, nullptr, nullptr);
        _client->ref();
        _client->setTimeout(_timeout);
        int res = _client->connectAsync(ip, port);
        if (res == 0) {
            _client->unref();
            _client = nullptr;
            return 0;
        }
        return 1;
    }
    int WiFiClient::connectCheck() {
        int res = _client->connectCheck();
        if (res == 0) return 0;
        if (res == -1) {
            _client->unref();
            _client = nullptr;
            return -1;
        }
        setSync(defaultSync);
        setNoDelay(defaultNoDelay);
        return 1;
    }

3. include/ClientContext.h 147line 에 추가.
    int connectAsync(CONST ip_addr_t* addr, uint16_t port) {
        err_t err = tcp_connect (_pcb, addr, port, &ClientContext::_s_connected);
        if (err != ERR_OK) return 0;
        _op_start_time = millis();
        return 1;
    }
    int connectCheck() {
        if (!_pcb) return -1;
        if (_pcb->state == ESTABLISHED) return 1;
        if (millis() - _op_start_time < _timeout_ms) return 0;
        abort();
        return -1;
    }

4. include/ClientContext.h 수정
    함수
        err_t _connected(struct tcp_pcb *pcb, err_t err)
    
        assert(_connect_pending);
        esp_schedule();
    
        if (_connect_pending) esp_schedule();
    로 변경

사용방법:

    WiFiClient client;
    int rv;
    if (client.connectAsync ("192.168.1.2", 123) == 0) return -1;
    do {
        rv = client.connectCheck ();
        if (rv == -1) return -1;
        if (rv ==  1) break;
        delay (1);
    } while (rv == 0);
    
    len = client.available ();
    if (0 < len) len = client.read (buff, len);
    
    len = client.availableForWrite ();
    if (0 < len) len = client.write (buff, len);

2018년 8월 3일 금요일

FileZilla FTP Server 한글 지원

FileZilla_Server-0_9_34.exe 를 설치하고, 윈도우 탐색기에서 FTP 로 접근하면 한글 파일 송/수신이 안된다.

ControlSocket.cpp 수정내용:

88line
m_useUTF8 = true; 를 -> m_useUTF8 = false; 로 변경

2301line
if (args == _T("UTF8 ON")) { } 부분 사용 안함.



모니터 프로그램의 폰트가 마음에 안들어서 변경 :

interface/StatusCtrl.cpp 수정내용:

295line
DEFAULT_GUI_FONT 를 -> SYSTEM_FIXED_FONT 로 변경



컴파일 :
1. FileZilla_Server-0_9_34/zlib/ 필요시 컴파일 한다.
생성파일:
Release/zlib.lib

2. FileZilla_Server-0_9_34 컴파일 한다.
생성파일:
Release/FileZilla server.exe
interface/Release/FileZilla Server Interface.exe


2016년 10월 18일 화요일

WiFi SSID 에 따라서 자동으로 IP 설정을 변경하기.

작업용으로 사용하는 노트북을 집에서는 고정 IP, 회사에서는 유동 아이피로 사용하고 있다.
매번 수동으로 IP 와 DNS 를 설정하는 것이 번거로우므로 간단한 해결책을 만들었다.

Step1. WiFiAutoConfig.bat 파일을 적당한 곳에 만든다.


@echo off
for /f %%i in ('netsh wlan show interface ^| find /C "SSID_NAME"') do (set X=%%i)
if %X% == 0 (
netsh interface ipv4 set address name="Wi-Fi" source=dhcp
timeout 1 >nul
netsh interface ipv4 set dnsservers name="Wi-Fi" source=dhcp
) else (
netsh interface ipv4 set address name="Wi-Fi" source=static address=192.168.219.73 mask=255.255.255.0 gateway=192.168.219.1 gwmetric=1
timeout 1 >nul
netsh interface ipv4 set dnsservers name="Wi-Fi" source=static address=1.214.68.2 register=primary validate=no
timeout 1 >nul
netsh interface ipv4 add dnsservers name="Wi-Fi" address=61.41.153.2 validate=no
)

  • "SSID_NAME" 에는 고정 IP로 사용하고자 하는 곳의 SSID 를 적는다.
  • "Wi-Fi" 이 이름은 PC에 따라서 다를 수 있다.
  • IP, SubnetMask, Gateway, DNS 등은 적당하게 설정한다.

Step2. Windows 작업 스케줄러에 등록한다.


제어판 → 관리 도구 → 작업 스케줄러 → 작업 만들기

일반탭

  • 이름 : "WiFi 자동 설정"
  • [선택] 사용자의 로그온 여부에 관계없이 실행
  • [체크] 가장 높은 수준의 권한으로 실행

트리거탭 → 새로 만들기

  • 작업 시작 : 이벤트 상태
  • 로그 : Microsoft-Windows-WLAN-AutoConfig/Operational
  • 원본 : WLAN-AutoConfig
  • 이벤트 : 8001
  • 고급설정 : [체크] 사용

동작탭 → 새로 만들기

  • 찾아보기 → WiFiAutoConfig.bat 선택

조건탭

  • 전원쪽은 모두 선택 해제하고,
  • [체크] 다음 네트워크 연결을 사용할 수 있는 경우에만 시작 → "모든 연결"

끝.

2015년 12월 3일 목요일

Windows 10 에서 오래된 hlp 파일 보기

조건:
Windows 7 에서 잘 동작하던 hlp 파일을 windows 10 으로 업그레이드후에는 열수가 없다.
기존 윈도우 백업에 있는 Windows.old/Windows/winhlp32.exe 는 잘 동작한다.

1. 기존 Windows.old/Windows/winhlp32.exe 파일을 적당한 위치(c:/temp)로 복사한다.

2. Win10-Hlp32-Fix.cmd 파일을 같은 폴더에 만들고 아래와 같이 넣는다.
@echo off
set crtpth=%CD%
takeown /f "%windir%\winhlp32.exe" >nul
icacls "%windir%\winhlp32.exe" /grant *S-1-5-32-544:F >nul
copy /y "%crtpth%\winhlp32.exe" %windir%
icacls "%windir%\winhlp32.exe" /setowner "NT Service\TrustedInstaller" >nul
echo.
echo Done.
echo.
echo Press any key to Exit
pause >nul
exit

3. Win10-Hlp32-Fix.cmd 파일을 관리자 모드로 실행시킨다.
   잘 동작하면 끝.



4. hlp 파일을 열때 9009 에러가 발생하면, 기존 Windows.old/Windows/ko-KR/winhlp32.exe.mui 파일을 Windows/ko-KR 로 복사한다.


끝.

2015년 5월 19일 화요일

포토샵 투명도 조절


Step1. 투명하게 만들기

화면 우측 하단의 LAYERS 창에서 Fill 수치를 100% 에서 원하는 정도로 변경합니다.

Before
After

Step2. 다시 불투명하게 만들기

상단메뉴 - Layer - Layer Mask - From Transparency 선택



Form Transparency 를 선택하면 우측 하단의 LAYERS 창에 Alpha 채널이 기존 그림의 우측에 선택된 채로 표시됩니다.
(혹시 선택이 안되었다면) 우측 Alpha 채널 그림을 마우스로 클릭해서 선택하고나서,

Ctrl+L 을 눌러서 Lavels 창을 엽니다.


Adjust highlight input level 값을 적당히 조절합니다.
위에서 알파를 50% 줬으니까, 여기서는 127을 주면 완전 불투명이 되겠죠.
그냥 'Auto' 눌러도 됩니다.


다시 불투명한 그림이 되었습니다.
마지막으로 우측하단 LAYERS 의 Alpha 채널에서 우측 버튼을 누르고


Apply Layer Mask 를 선택하면 완료!

2011년 4월 19일 화요일

안드로이드 Android GPS 개발시 좌표 지정하는 방법

요즘 Professional Android2 Application Development 를 보고 있는데
GPS프로그래밍을 하면서 가상 좌표를 안드로이드 에뮬레이터에 넣는것에 막혀 있었다.
책에있는 코드를 휴대폰에 넣으면 잘 동작한다.

해결방법은

1. Setting - Application - Development - Allow mock locations 체크해제를 하면 GPS가 동작 가능 상태가 된다.

2. Location & sequrity - Use GPS satellites 체크되어 있는지 확인하고,

3. Eclips 메뉴 - Window - Open Perspective - DDMS 를 선택하면 나오는 창에서 Emulator control 하단에 Manual Tab 에서 [Send]버튼을 누르면 해당 좌표가 GPS좌표로 설정된다.

* 이때 Manual tab의 항목이 disable 되어 있으면 Devices 창 우측의 STOP 버튼을 눌러준다.

* 인터넷 검색중에 Setting - Date & Time 에서 Automatic 체크해제하고 time zone 을 seoul로 설정하라는 글을 봤는데 안해도 무방했음. but 설정을 하면 시간이 정확하게 나와서 좋음

* 안드로이드 에뮬레이터 : Android 2.2 - API Level 8
* Eclipse IDE for Java Developers : Helios Service Release 2

2011년 4월 11일 월요일

MFC에서 GDI+ 사용하기

1. Anti alias 라인을 그리기 위한 GDI+ 를 사용

Step1. stdafx.h 에 선언추가

#include
#pragma comment(lib, "gdiplus")
using namespace Gdiplus;



Step2. 초기화

[ProjectName]App.c 파일의 InitInstance() 함수에 초기화를 추가한다.

GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

그리고 아래 두 라인을 광역변수로 추가한다.

GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;



Step3. 정리

[ProjectName]App.c 파일의 ExitInstance() 함수(없으면 만든다)에 정리코드를 추가한다.

GdiplusShutdown(gdiplusToken);



Step4. 사용

Graphics graphics( pDC->m_hDC );
graphics.SetSmoothingMode( SmoothingModeAntiAlias );
Color c(50,200,255);
Pen p(c, 1.0);
Gdiplus::PointF p1, p2;
p1.X = 0.0;
p1.Y = 0.0;
p2.X = 100.0;
p2.Y = 10.0;

graphics.DrawLine (&p, p1, p2);



2. Pen : 연결된 선의 꺽임 처리

p.SetLineJoin (LineJoinRound);

enum LineJoin
{
    LineJoinMiter = 0,
    LineJoinBevel = 1,
    LineJoinRound = 2,
    LineJoinMiterClipped = 3
};






3. Pen : 선의 시작과 끝부분 처리

p.SetStartCap(LineCapRoundAnchor);
p.SetEndCap(LineCapArrowAnchor);

enum LineCap
{
    LineCapFlat = 0,
    LineCapSquare = 1,
    LineCapTriangel = 3,

    LineCapNoAnchor = 0x10,
    LineCapSquareAnchor = 0x11,
    LineCapRoundAnchor = 0x12,
    LineCapDiamondAnchor = 0x13,
    LineCapArrowAnchor = 0x14,

    LineCapCustom = 0xff,
    LineCapAnchorMask = 0xf0
}





4. 안티엘러어싱 적용

graphics.SetSmoothingMode(SmoothingModeHighQuality);

enum SmoothingMode
{
//XP이상 사용가능
SmoothingModeInvalid =QualityModeInvalid,
SmoothingModeDefault =QualityModeDefault,
SmoothingModeHighSpeed =QualityModeLow,
SmoothingModeHighQuality =QualityModeHigh,
SmoothingModeNone,
SmoothingModeAntiAlias,
#if(GDIPVER>=0x0110)
//비스타 이상 버전에서만 사용가능..
SmoothingModeAntiAlias8x4 =SmoothingModeAntiAlias,
SmoothingModeAntiAlias8x8
#endif//(GDIPVER>=0x0110)
};




5. 부드러운 선그리기

graphics.DrawCurve(&p, points, 6, 0.5f);

Struct DrawCurve(const Pen* pen, const Pointf* points, INT count, REAL tension);
arg1: Pen클래스 객체의 주소
arg2: Point배열 클래스의 주소
arg3: 두번째로 전달 받은 Point배열의 클래스 객체의 수..
arg4: 곡선을 그릴때 각이 생기지 않도록 끝을 강제로 늘려주는 장력을 명시 한다.




 

2011년 4월 8일 금요일

VC2008 MFC 인쇄관련 버그

Windows7 에서 VC2008 MFC Wizard 로 생성한 project 의 인쇄관련 버그



1. GetStockObject

void CView::OnPrint(CDC* pDC, CPrintInfo* pInfo) { } 함수에서

    pDC->SelectObject (GetStockObject(WHITE_BRUSH));

'SelectObject' 실행중 오류발생 -> API를 사용해서 해결했음

    ::SelectObject (pDC->m_hDC, GetStockObject(WHITE_BRUSH));



2. System menu

인쇄미리보기중 창의 우측 상단에 있는 최소, 최대, 닫기 버튼을 클릭하면 프로그램이 정지함

System menu 를 일시적으로 삭제함으로 회피했음

// 인쇄미리보기 시작시 System menu 를 삭제함
void CFrictionTesterView::OnBeginPrinting(CDC*, CPrintInfo*) {
    CMainFrame* mf = (CMainFrame*)AfxGetMainWnd();
    LONG style = GetWindowLong(mf->m_hWnd, GWL_STYLE);
    style &= ~WS_SYSMENU;
    SetWindowLong(mf->m_hWnd, GWL_STYLE, style);
}


// 인쇄미리보기 종료시 System menu 를 복구함
void CFrictionTesterView::OnEndPrinting(CDC*, CPrintInfo*) {
    CMainFrame* mf = (CMainFrame*)AfxGetMainWnd();
    LONG style = GetWindowLong(mf->m_hWnd, GWL_STYLE);
    style |= WS_SYSMENU;
    SetWindowLong(mf->m_hWnd, GWL_STYLE, style);
}

2011년 2월 11일 금요일

VC++ MFC에서 ActiveX 사용하기

Visual C++ 6.0 기준 (VC++ 9.0필요)

ActiveX 만드는 방법

1. File - New 에서 MFC ActiveX ControlWizard 선택
-> 적당히 ActiveX project를 생성시킨다.


2. ClassView 에서 가장 처음항목(아이콘이 고리모양임) "_ProjectName"
여기에서 우측버튼을 눌러 Add Method 를 선택해서 외부로 공개할 함수를 등록한다.



"_ProjectNameEvents" 는 CallBack 함수를 등록하는 곳이다.
ActiveX 에서 자신을 로드한 부모 프로세서로 명령을 보낸다.



ActiveX 링크파일 만들기

1. 전체 프로젝터를 다른 폴더로 목사한다음 Visual C++ 9.0 에서 로드한다.

2. ClassView 에서 우측버튼을 눌러서 "추가 - 클래스" 를 선택하고
"ActiveX 컨트롤의 MFC 클래스" 를 선택한다.
(* VC6에는 "추가" 항목이 없다)




3. 사용 가능한 ActiveX 컨트롤 항목에서 원하는 이름을 선택한후, 인터페이스 항목을 선택하고 ">" 버튼을 누르면 생성된 클래스에 이름이 나온다. "마침" 을 누르면 인터페이스 클래스가 생성 되었다.




ActiveX 사용하는 방법

1. 위에서 생성된 인터페이스 클래스를 Visual C++ 6.0 project 로 가져가서 일반 class처럼 사용하면 된다.



CallBack event 수신하기

1. 작업 class의 h 파일에 "DECLARE_EVENTSINK_MAP" 를 추가한다.

//{{AFX_MSG(CGenesisCtrlView)
afx_msg void OnTimer(UINT nIDEvent);
...
DECLARE_EVENTSINK_MAP ()
//}}AFX_MSG

2. CallBack 함수 원형을 참조해서 cpp 파일에 "ON_EVENT" 를 추가한다.

BEGIN_EVENTSINK_MAP(CGenesisCtrlView, CFormView)
//{{AFX_EVENTSINK_MAP(CGenesisCtrlView)
ON_EVENT(CGenesisCtrlView, -1, 1, OnMoveHole, VTS_R8 VTS_R8 VTS_R8)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
// -1은 ID가 없기 때문임. Dialog등에 속해있다면 그 ID를 사용함
// 1은 함수번호.

3. OnMoveHole(double,double,double) 함수를 만들면 호출됨.

2009년 10월 14일 수요일

Photo editor online PIXLR


웹브라우저 상에서 동작 가능한 Flash로 만들어진 그래픽 편집 프로그램.
포토샵 대용으로 쓰기에 충분함!
Link -> http://pixlr.com/editor/
 

2009년 6월 17일 수요일

Favicon - 주소표시줄에 아이콘 넣기

아래와 같이 하면 주소표시줄에 원하는 아이콘을 넣을 수 있다.

<head>
<link href="icon.ico" rel="shortcut icon">
</head>

2008년 1월 14일 월요일

JAVA Font Metrics




public void paintComponent (Graphics g) {

    Graphics2D g2 = (Graphics2D)g;

    String ss = "Pjw";
    int baseline1 = 230;
    int baseline2;
    int x1=30, x2, y1, y2, y3, y4;

    Font ft = new Font ("serif", Font.BOLD, 200);
    FontMetrics fm = g.getFontMetrics (ft);
    g.setFont (ft);

    x2 = x1 + fm.stringWidth (ss);
    y1 = baseline1 - fm.getAscent ();
    y2 = baseline1 + fm.getDescent ();
    y3 = baseline1 + fm.getDescent () + fm.getLeading ();
    baseline2 = baseline1 + fm.getHeight();
    y4 = baseline2 - fm.getAscent ();

    g2.setPaint (new Color(0x000000));
    g.drawString(ss,x1,baseline1);

    g2.setPaint (new Color(0x000080));
    g.drawLine(x1-20,y1,x2+20,y1);
    g2.setPaint (new Color(0x0000FF));
    g.drawLine(x1-20,baseline1,x2+20,baseline1);

    g2.setPaint (new Color(0x008000));
    g.drawLine(x1-20,y2,x2+20,y2);

    g2.setPaint (new Color(0x00FF00));
    g.drawLine(x1-20, y3, x2+20, y3);

    g2.setPaint (new Color(0x606060));
    g.drawString(ss, x1, baseline2);
    g.drawLine(x1-20,baseline2,x2+20,baseline2);

    g2.setPaint (new Color(0xFF0000));
    g.drawLine (x2-20, y4, x2+20, y4);

    g2.setPaint (new Color(0x800080));
    g.drawLine (x1, y1-20, x1, y4+20);
    g2.setPaint (new Color(0x008080));
    g.drawLine (x2, y1-20, x2, y4+20);

}

2008년 1월 3일 목요일

Java 메모리 사용량 알기

Java 에서 사용하고 있는 힙 크기 측정방법

// Runtime 개체를 받아온다.
Runtime rt = Runtime.getRuntime();

// 할당된 힙 메모리
rt.totalMemory()

// 힙 내에서 남아있는 메모리
rt.freeMemory()

// 힙 내에서 사용중인 메모리 구하는 방법
rt.totalMemory()-rt.freeMemory()

// Java 카비지 컬렉터를 실행한다.
rt.gc (); // 또는 System.gc()

* 위 함수는 힙 크기만을 측정할 뿐이며 Java 내부적으로 사용된 메모리는 측정되지 않는다.

2007년 10월 13일 토요일

Java 3D 회전 & 2D 메모리 버퍼

최근에 Java에서 3D그래픽 처리를 하기 위해서 예전에 C로 만들어 두었던 3D소스를 Java로 포팅했다.
Java와 C의 문법이 아주 비슷하기 때문에 몇 가지만 수정하니 바로 동작 되었다.



3D 회전 코드

double cos_th, sin_th, cos_pi, sin_pi, cam_rr;
int gx, gy;

void setCamera (double th, double pi, double r) {
    cos_th = Math.cos (-th);
    sin_th = Math.sin (-th);
    cos_pi = Math.cos (-pi);
    sin_pi = Math.sin (-pi);
    cam_rr = r;
}

void rotPoint (double x, double y, double z) {
    double x1, x2, y1, z1;
   
    x1 = -cos_th*x - sin_th*y;
    y1 = -sin_th*x + cos_th*y;
    z1 = -cos_pi*z - sin_pi*x1;
    x2 = -sin_pi*z + cos_pi*x1;
    x = cam_rr - x2;
    y = y1 / x;
    z = z1 / x;
    gx = (int)(y);
    gy = (int)(z);
}


메모리 버퍼에 그림을 그리고 보여주는 코드

int bitmap[];
BufferedImage bi;

void init (int width, int height) {
    bi = new BufferedImage (width, htight, BufferedImage.TYPE_INT_RGB);
    bitmap = new int[width*height];
}

void draw (Graphics g, int x, int width, int y, int height) {
   
    // Modify the values in the pixels array at (0, 0, width, height)
   
    bi.setRGB (0, 0, width, height, bitmap, 0, width);
    g.drawImage (bi, x, y, null);
}

코드의 성능은 200*200 크기에서는 110FPS, 1400*1000 에서는 4.8FPS.
3D 계산이 많기는 하지만 너무나 큰 차이가 나서 어디가 문제인지 찾아보니 bi.setRGB() 와 g.drawImage() 를 빼면 200*200 크기에서는 200FPS, 1400*1000 에서는 28FPS.
그림을 실제 화면으로 뿌려 주는데 83% 의 시간을 차지하고 있다.


개선된 메모리 버퍼에 그림을 그리고 보여주는 코드

int bitmap[];
MemoryImageSource source;
Image image;

void init (int width, int height) {
    bitmap = new int[width*height];
    source = new MemoryImageSource (width, height, bitmap, 0, width);
    source.setAnimated (true);
    image = createImage (source);
}

void draw (Graphics g, int x, int width, int y, int height) {
   
    // Modify the values in the pixels array at (0, 0, width, height)
   
    source.newPixels (0, 0, width, height);
    g.drawImage (image, x, y, null);
}

코드의 성능은 200*200 크기에서는 170FPS. 1400*1000 에서는 14.2FPS 로 296% 증가.

2007년 10월 8일 월요일

Java Thread & Swing

Java 에서 일반적인 방식으로 GUI 를 다루는것은 안전하다. 그러나 GUI 에 영향을 주는 명령을 수행하는 thread 를 사용하거나 표준적인 event 가 아닌 다른 event 에 응답해서 이미 스크린상에 보여지고 있는 GUI 를 조작할 경우에는 다음 규칙을 지켜야 한다.

규칙: Swing component 가 realized 되고 있다면 그 component 에 영향을 주거나 의존하는 모든 코드들은 event-dispatching thread 안에서 실행 되어야 한다. (일부 thread-safe 한 API 도 있다)

realized 란. 다음 세 명령어에 의해 이루어 진다.
[ setVisible(true), show, pack ]

예외1. repaint(), revalidate() thread 에서 안전하다.
예외2. Listener리스트는 수정은 thread 에서 안전하다.


Event-Dispatching Thread 에서 코드를 실행하는 방법
GUI 초기화가 이루어진 이후의 대부분의 작업은 자동적으로 event-dispatching thread 에서 일어난다. 일단 GUI가 realized 되면, 버튼을 누르거나 마우스를 클릭하는 등의 이벤트가 프로그램의 대부분을 구성하게 되는데, 이러한 이벤트들은 항상 event-dispatching thread 에서 다루어진다.

그러나 통신 프로그램이나 thread 방식의 프로그램은 GUI가 가시화 된 이후에 non-event-driven GUI 작업을 수행할 때도 있다.

SwingUtilities 클래스는 event-dispatching thread 안에서 코드를 실행하도록 돕는 두개의 메소드를 제공한다.


invokeLater
이 메소드는 일부 코드가 event-dispatching thread 에서 실행될것을 요청한다. 이 메소드의 결과는 코드가 실행되기를 기다리지 않고 즉시 반환된다. 보류중인 모든 AWT 이벤트가 처리된 뒤에 실행된다.

Runnable InvokeTest = new Runnable() {
    public void run() {
        System.out.println("Thread " + Thread.currentThread());
    }
};
SwingUtilities.invokeLater(InvokeTest);


invokeAndWait
invodeLater 와 비슷한 기능을 한다. 다른점이라면 이 메소드는 코드가 실행되는동안 기다린다는 것이다. 이 메소드는 EventDispatchThread로 부터 호출하면 안된다. 이 메소드보다 invokeLater 메소드를 추천한다.

Runnable InvokeTest = new Runnable() {
    public void run() {
        System.out.println("Thread " + Thread.currentThread());
    }
};
try {
    SwingUtilities.invokeAndWait(InvokeTest);
} catch (Exception e) {
    e.printStackTrace();
}

2005년 9월 6일 화요일

[보내는 메일서버 - 인증필요] 일때 인증하는 방법

EHLO 의 응답으로 250-AUTH LOGIN 이 나오면 인증가능

client -> AUTH LOGIN        // 시작을 알림
server -> 334 VXNlcm5hbWU6        // Username: 의 BASE64표기
client -> cGp3MDAwMjc=        // ID 를 BASE64 로 보냄
server -> 334 UGFzc3dvcmQ6        // Password: 의 BASE64표기
client -> cGp3MDAwMjc=        // PW 를 BASE64 로 보냄
server -> 235 ok, go ahead (#2.0.0)        // 성공!
server -> 535 authorization failed (#5.7.0)        // 오류!

<<< 220 smtp4.mail.krn.yahoo.com ESMTP
>>> EHLO TGNT04
<<< 250-smtp4.mail.krn.yahoo.com
250-AUTH LOGIN PLAIN XYMCOOKIE
250-PIPELINING
250 8BITMIME
>>> AUTH LOGIN
<<< 334 VXNlcm5hbWU6
>>> cGp3MDAwMjc=
<<< 334 UGFzc3dvcmQ6
>>> YWRvcHBp
<<< 235 ok, go ahead (#2.0.0)
>>> MAIL FROM: <pjw00027@yahoo.co.kr>
<<< 250 ok
>>> RCPT TO: <pjw@toolgen.com>
<<< 250 ok
>>> DATA
<<< 354 go ahead
>>> Message-ID: <001201c5b2e9$67aafb70$bd349edd@TGNT04>
From: =?ks_c_5601-1987?B?udrB+L/s?= <pjw00027@yahoo.co.kr>
To: <pjw@toolgen.com>
Subject: t1
...
------=_NextPart_000_000F_01C5B334.D6813370--

.
<<< 250 ok 1126014399 qp 5511
>>> QUIT
<<< 221 smtp4.mail.krn.yahoo.com

2004년 9월 15일 수요일

Color table

C로 만드는 색상표 소스.


#include "../common/common.h"
#include "../common/gif.h"

int l, r, n, cb,cw;
double dx, dy, mx, my;

void SetBox (class GIFIMAGEMAP *gif, int _r, int _g, int _b) {
    char str[30];
    int i, c;
   
    if (n < r) {
        mx += dx;
        my += dy/2;
        n++;
    } else if (n < r*2) {
        my += dy;
        n++;
    } else if (n < r*3) {
        mx -= dx;
        my += dy/2;
        n++;
    } else if (n < r*4) {
        mx -= dx;
        my -= dy/2;
        n++;
    } else if (n < r*5) {
        my -= dy;
        n++;
    } else if (n < r*6) {
        mx += dx;
        my -= dy/2;
        n++;
        if (n == r*6) {
            r++;
            n = 0;
            my -= dy;
        }
    } else {
        r++;
        n = 0;
        my -= dy;
    }
   
    _r *= 51;
    _g *= 51;
    _b *= 51;
    c = gif->SetColorRGB (_r,_g,_b);
    for (i=-int(dy/2); i<dy/2; i++) {
        gif->Line (mx-l, my, mx-l/2, my+i, c);
        gif->Line (mx+l, my, mx+l/2, my+i, c);
    }
    gif->Bar (mx-l/2, my-dy/2, mx+l/2, my+dy/2, c);
   
    gif->Line (mx-l, my, mx-l/2, my-dy/2, cb);
    gif->Line (mx-l, my, mx-l/2, my+dy/2, cb);
    gif->Line (mx+l, my, mx+l/2, my-dy/2, cb);
    gif->Line (mx+l, my, mx+l/2, my+dy/2, cb);
    gif->Line (mx-l/2, my-dy/2, mx+l/2, my-dy/2, cb);
    gif->Line (mx-l/2, my+dy/2, mx+l/2, my+dy/2, cb);
   
    sprintf (str, "%02X%02X%02X", _r,_g,_b);
    if (_r*76+_g*150+_b*29 < 38250) c = cw;
    else c = cb;
    gif->TextOutBig (mx-21, my-12, str, c, 7);
    gif->TextOutBig (mx-20, my-12, str, c, 7);
    sprintf (str, "%d.%d.%d", _r,_g,_b);
    gif->TextOut (mx-strlen(str)*3, my+4, str, c);
}

void main () {
    FILE *fp;
    class GIFIMAGEMAP gif;
    int c, i;
    char s[2];
    char code[] = {
    4,4,4, 5,5,5, 0,0,0, 1,1,1, 2,2,2, 3,3,3,
    5,4,3, 5,4,4, 5,3,4, 5,4,5, 4,3,5, 4,4,5, 3,4,5, 4,5,5, 3,5,4, 4,5,4, 4,5,3, 5,5,4,
    4,3,2, 4,3,3, 5,3,3, 4,2,3, 4,3,4, 5,3,5, 3,2,4, 3,3,4, 3,3,5, 2,3,4, 3,4,4, 3,5,5, 2,4,3, 3,4,3, 3,5,3, 3,4,2, 4,4,3, 5,5,3,
    3,2,1, 3,2,2, 4,2,2, 5,2,2, 3,1,2, 3,2,3, 4,2,4, 5,2,5, 2,1,3, 2,2,3, 2,2,4, 2,2,5, 1,2,3, 2,3,3, 2,4,4, 2,5,5, 1,3,2, 2,3,2, 2,4,2, 2,5,2, 2,3,1, 3,3,2, 4,4,2, 5,5,2,
    2,1,0, 2,1,1, 3,1,1, 4,1,1, 5,1,1, 2,0,1, 2,1,2, 3,1,3, 4,1,4, 5,1,5, 1,0,2, 1,1,2, 1,1,3, 1,1,4, 1,1,5, 0,1,2, 1,2,2, 1,3,3, 1,4,4, 1,5,5, 0,2,1, 1,2,1, 1,3,1, 1,4,1, 1,5,1, 1,2,0, 2,2,1, 3,3,1, 4,4,1, 5,5,1,
    4,2,0, 1,0,0, 2,0,0, 3,0,0, 4,0,0, 5,0,0, 4,0,2, 1,0,1, 2,0,2, 3,0,3, 4,0,4, 5,0,5, 2,0,4, 0,0,1, 0,0,2, 0,0,3, 0,0,4, 0,0,5, 0,2,4, 0,1,1, 0,2,2, 0,3,3, 0,4,4, 0,5,5, 0,4,2, 0,1,0, 0,2,0, 0,3,0, 0,4,0, 0,5,0, 2,4,0, 1,1,0, 2,2,0, 3,3,0, 4,4,0, 5,5,0,
    5,3,1, 5,3,2, 4,2,1, 3,1,0, 3,0,1, 4,1,2, 5,2,3, 5,1,3, 5,2,4, 4,1,3, 3,0,2, 2,0,3, 3,1,4, 4,2,5, 3,1,5, 3,2,5, 2,1,4, 1,0,3, 0,1,3, 1,2,4, 2,3,5, 1,3,5, 2,4,5, 1,3,4, 0,2,3, 0,3,2, 1,4,3, 2,5,4, 1,5,3, 2,5,3, 1,4,2, 0,3,1, 1,3,0, 2,4,1, 3,5,2, 3,5,1, 4,5,2, 3,4,1, 2,3,0, 3,2,0, 4,3,1, 5,4,2,
    5,2,0, 5,1,0, 5,2,1, 4,1,0, 4,0,1, 5,1,2, 5,0,1, 5,0,2, 5,0,3, 5,0,4, 5,1,4, 4,0,3, 3,0,4, 4,1,5, 4,0,5, 3,0,5, 2,0,5, 1,0,5, 2,1,5, 1,0,4, 0,1,4, 1,2,5, 0,1,5, 0,2,5, 0,3,5, 0,4,5, 1,4,5, 0,3,4, 0,4,3, 1,5,4, 0,5,4, 0,5,3, 0,5,2, 0,5,1, 1,5,2, 0,4,1, 1,4,0, 2,5,1, 1,5,0, 2,5,0, 3,5,0, 4,5,0, 4,5,1, 3,4,0, 4,3,0, 5,4,1, 5,4,0, 5,3,0
    };
   
    l = 42;
    r = n = 0;
    dx = 1.5*l;
    dy = 1.732050807568877*l;
    mx = 650.0;
    my = 700.0;
   
    gif.CreateCanvas (1300, 1400);
    cb = gif.SetColor (0x000000);
    cw = gif.SetColor (0xFFFFFF);
   
    // 216
    for (i=0; i<sizeof(code)/3; i++)
        SetBox (&gif, code[i*3],code[i*3+1],code[i*3+2]);
    for (i=0; i<54; i++)
        SetBox (&gif, 0,0,0);
   
    fp = fopen ("hi.gif", "wb");
    gif.PrintCanvas (fp);
    fclose (fp);
   
    gif.DistroyCanvas ();
}

2002년 10월 9일 수요일

Method: Pearson correlation

Pearson correlation

개념은 다음과 같다.

        r = X와 Y가 함께 변하는 정도 / X와 Y가 따로 변하는 정도

Gene X 와 Y 의 Pearson 상관 r 을 구하는 식은 다음과 같다.


* 결과의 해석
r 값은 X 와 Y 가 완전히 동일하면 +1, 전혀 다르면 0, 반대방향으로 완전히 동일
하면 –1 을 가진다. 결정계수 (coefficient of determination) 는 r^2 로 계산하며 이것은 X 로부터 Y 를 예측할 수 있는 정도를 의미한다.

일반적으로
    r이 -1.0과 -0.7 사이이면, 강한 음적 선형관계,
    r이 -0.3과 -0.7 사이이면, 뚜렷한 음적 선형관계,
    r이 -0.1과 -0.3 사이이면, 약한 음적 선형관계,
    r이 -0.1과 +0.1 사이이면, 거의 무시될 수 있는 선형관계,
    r이 +0.1과 +0.3 사이이면, 약한 양적 선형관계,
    r이 +0.3과 +0.7 사이이면, 뚜렷한 양적 선형관계,
    r이 +0.7과 +1.0 사이이면, 강한 양적 선형관계
로 해석한다.

2002년 10월 4일 금요일

Tray icon 설계와 관련 Win32 API

Icon 은 32, 16 의 두가지가 있는데 32->16시 4pixel 을 하나로 합하고,
16->32시 주변의 평균을 취해서 아이콘이 흐려진다.
tray icon 은 32 크기를 사용하는데 (0,0) 을 기준으로 했을때
(1,1) , (3,1) , (1,3) , (3,3) ... 에 있는 점만 모아서 16형태로 보여준다.
원래 16형태 아이콘은 정상적으로 표현되지 않는다.




시스템 트레이에 아이콘 설치하는 방법

NOTIFYICONDATA systemtray;

// 아이콘등록: hwnd:부모, uID:트레이아이디는, messageID:Event 발생시 날아오는 ID
BOOL SystemTray_Register (HWND hwnd, UINT uID, UINT messageID) {
    systemtray.cbSize = sizeof (systemtray);
    systemtray.hWnd = hwnd;
    systemtray.uID = uID;
    systemtray.uFlags = NIF_MESSAGE;
    systemtray.uCallbackMessage = messageID;
    return Shell_NotifyIcon (NIM_ADD, &systemtray);
}

// 설명바꾸기(uID는 동일함으로 그냥 둠): iconID:resource 에 있는 아이콘 ID, szTip:새ToolTip
BOOL SystemTray_Modify (UINT iconID, char *szTip) {
    systemtray.uFlags = NIF_ICON NIF_TIP;
    systemtray.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(iconID));
    strcpy (systemtray.szTip, szTip);
    return Shell_NotifyIcon (NIM_MODIFY, &systemtray);
}

// 삭제(uID는 동일함으로 그냥 둠)
BOOL UnRegisterSystemTray () {
    systemtray.uFlags = 0;
    return Shell_NotifyIcon (NIM_DELETE , &systemtray);
}

SystemTray_Register (hwnd, 1, WM_USER+1);
SystemTray_Modify (IconID, "Tool Tip");

2000년 11월 25일 토요일

Html 사용법, 팁

1. 개채의 속성 출력

<img id='id1' src='test.gif'>

<script type="text/javascript">
for (propName in id1.style) {
    document.write('id1.',propName,'="',id1.style[propName],'"<BR>');
}
</script>


2. 마우스가 올라가면 그림이 변함

<script language="JavaScript">
if (document.images) {
    var go_on = "on.gif";
    go_off= "off.gif";
}
function SwapImage (id, name) {
    if (document.images) document.images[id].src=eval(name);
}
</script>

<img name="id1" src="off.gif"
    onMouseOver="SwapImage ('id1', 'go_on');"
    onMouseOut ="SwapImage ('id1', 'go_off');"
>


3. 입력폼이 타당한지 검사

<script language=JavaScript>
function check_form () {
    if (document.form.name.value == "") {
        alert ('error');
        form.name.focus();
        return false;
    }
    return true;
}
</script>

<form name='form' method='post' action='$pgname;' onsubmit='return check_form ()'>
...
</form>



4. 타이머 설정

<script language=JavaScript>
var ident;
function TimeOutFunction () {
    window.clearTimeout (ident);
    window.status="timer off";
}
ident = window.setTimeout ("TimeOutFunction ()", 3000);
window.status="set 3,000ms timer";
</script>



5. iframe 크기조절

<iframe name='border_iframe' scrolling='no' frameborder='0' width='652' height='500' src='board.cgi'></iframe>

iframe 의 마지막 부분에 다음을 넣으면 된다.

<div id='endofhtml'></div>
<script language=JavaScript>
parent.document.all.border_iframe.height = endofhtml.offsetTop;
</script>



6. 파일 올리기

<form enctype="multipart/form-data" method=post action="http://Localhost/Scripts/CGI.exe">
<input type=file name="file" size=40>
</form>



7. select 에서 값을 가져오기

<script language=JavaScript>
function ChangeSelectOption1() {
    spp = document.form.selitem.selectedIndex;
    alert ("Method1="+document.form.selitem.options[spp].value);
    return;
}
function ChangeSelectOption2() {
    alert ("Method2="+document.form.selitem2.value);
    return;
}
</script>

<form name="form">
<SELECT name='selitem' OnChange='javascript:ChangeSelectOption()'>
        <option label="3.7.0" value="pm3_3.7.1">ALL</option>
    <OPTGROUP label="PortMaster 3">
        <option label="3.7.1" value="pm3_3.7.1">PortMaster 3 with ComOS 3.7.1
        <option label="3.7" value="pm3_3.7">PortMaster 3 with ComOS 3.7
    </OPTGROUP>
    <OPTGROUP label="IRX">
        <option label="3.7R" value="IRX_3.7R">IRX with ComOS 3.7R
        <option label="3.5R" value="IRX_3.5R">IRX with ComOS 3.5R
    </OPTGROUP>
</SELECT>
</form>