'Programmings'에 해당되는 글 51건

  1. 2008.09.08 VS2005 응용프로그램 에러.. "응용 프로그램 구성이 올바르지 않기 때문에 이 응용 프로그램을 시작하지 못했습니다..." 3
  2. 2008.09.06 전원 상태를 알아오는 SYSTEM_POWER_STATUS struct
  3. 2008.09.05 Windows Power management API - PBT_APMPOWERSTATUSCHANGE Event 1
  4. 2008.08.20 GetCurrentDirectory()를 이용한 Windows에서 현재경로 받아오기.. 1
  5. 2008.08.19 Windows 프로그램을 시작 프로그램으로 등록하기
  6. 2008.08.11 GetMessage() 와 PeekMessage() 1
  7. 2008.07.31 Windows Device Driver 관련 용어들..
  8. 2008.07.28 MSDN 키보드 입력 작동 방식 스크랩
  9. 2008.07.24 키보드 키의 상태값을 알아오기
  10. 2008.04.24 CVI Control Modes for Generating Events
2008. 9. 8. 13:55

VS2005 응용프로그램 에러.. "응용 프로그램 구성이 올바르지 않기 때문에 이 응용 프로그램을 시작하지 못했습니다..."



프로그램을 짜다보면 희안한 그리고 황당한 일을 많이 겪는다.

'VS2005' 에서 간단한 테스트 프로그램을 작성하고 동작을 잘하는 것을 확인하고나서 다른 PC로 실행파일을 옮겨 실행을 시키니 다음과 같은 에러 메시지가 뜬다.
응용 프로그램 구성이 올바르지 않기 때문에 이 응용 프로그램을 시작하지 못했습니다. 이 문제를 해결하려면 응용 프로그램을 다시 설치하십시오.
사용자 삽입 이미지

같은 프로그램을 동일한 OS가 설치된 다른 기계에서 실행이 되지 않는 이런.. XX같은 일이... -_-;;
해결방안을 찾기 위해 구글이며 네이버며.. 여기 저기 뒤진 결과 일단은 해결을 했다.

가장 간단한 방법은 'vcredist_x86.exe'를 에러가 발생하는 PC에 설치를 해주면 된다.
VS2005가 설치된 PC에서 "C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86"폴더를 확인하자.
vcredist_x86.exe 라는 파일을 발견할 수 있을 것이다. 이 녀석을 테스트 하려 하는 PC에 설치를 한 뒤 에러가 발생했던 테스트 프로그램을 실행시켜 보면 정상적으로 동작하는 것을 확인 할 수 있다.
혹시... visual studio가 설치 되지 않아 파일을 찾을 수 없는 사람이라면... 아래 파일을 받아서 사용하면 된다.

다른 방법으로는 mfc80.dll, msvcr80.dll 등을 실행파일과 같은 폴더에 복사한 뒤 프로그램을 실행하면 된다고들 하는데.. 본인의 경우에서는 그렇지 않았다. 대신 위에서 설명한 vcredist_x86.exe 를 설치한 뒤에 정상적으로 동작을 하였다.

이런 현상이 발생하는 이유는 다음과 같다.
Windows XP에서는 DLL Hell(새로운 프로그램을 설치할때 다른 프로그램이 사용하는 DLL을 덮어 쓰거나 혹은 버전의 불일치로 오는 문제로 기존의 프로그램들이 제대로 동작하지 않는 경우가 있다.)을 빠져나가려고 Side-by-Side Assembly라는 개념을 만들었다.
이건 여러 버전의 DLL을 동시에 시스템에 존재할 수 있게 해주고, DLL을 사용하는 응용프로그램이 원하는 DLL 버전을 골라서 쓸 수 있도록 해주는 방법이다.

SideBySideAssembly 의 강력한 점은 응용프로그램에서 직,간접적으로 로드하는 모든 DLL이 이 설정의 영향을 받는다는 것이다. 이전에는 응용프로그램이 로드한 DLL에 의해서 간접적으로 로드되는 DLL을 제어할 수 있는 방법이 없었다.

이러한 새로운 방식으로 기존방식대로 VS.NET 라이브러리를 복사하는것으로 끝나지 않고 배포를 위한 별도의 작업이 필요하게 된다.

문제 해결에 대한 페이지
http://www.serious-code.net/moin.cgi/RedistributingVisualCppRunTimeLibrary
http://www.codeproject.com/cpp/vcredists_x86.asp
http://cafe.naver.com/solidcode.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=8


- 홍가일보 블로그에서 살짝 가져옴... ^^;

아.. 그런데.. 이런 응용프로그램을 만들어 배포할 경우에는 어쩌지? -_-;;


2008. 9. 6. 10:24

전원 상태를 알아오는 SYSTEM_POWER_STATUS struct



'SYSTEM_POWER_STATUS' 는 Windows System에서 전력관리에 사용되는 구조체이다.

현재 동작하는 Windows System의 전원상태에 대한 정보를 담고 있다고 보면 된다. 전원에 대한 상태라는 것은 현재 사용하고 있는 전원이 AC인지 아니면 배터리를 사용하고 있는지에 대한 정보, 또 배터리를 사용하고 있다면 남아있는 배터리의 양이라든지 life time이라든지에 대한 정보를 말한다.

이녀석에 대한 정보를 가져오기 위해서는 'GetSystemPowerStatus()'라는 함수를 사용하게 된다. GetSystemPowerStatus()함수의 인자로 SYSTEM_POWER_STATUS가 사용되고, 현재 전원에 대한 상태정보를 인자로 사용된 이 구제체로 복사를 해오는 것이다.

현재 전원에 대한 상태정보를 알기 위해서 이 구조체를 사용하기만 하면된다.
Syntax를 보면 다음과 같다.
typedef struct _SYSTEM_POWER_STATUS {
BYTE ACLineStatus;
BYTE BatteryFlag;
BYTE BatteryLifePercent;
BYTE Reserved1;
DWORD BatteryLifeTime;
DWORD BatteryFullLifeTime;
} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;
ACLineStatus
: AC power의 상태를 말한다. (0 : Offline, 1 : Online, 255 : Unknown status)

BatteryFlag
: 배터리의 charge status를 나타낸다.
  1    : High-the battery capacity is at more than 66 %
  2    : Low—the battery capacity is at less than 33 %
  4    : Critical—the battery capacity is at less than 5 %
  8    : Charging
  128 : No system battery
  255 : Unknown status—unable to read the battery flag information

BatteryLifePercent
남아있는 배터리의 양을 %로 표현한다. 0 ~ 100 사이의 값으로 표현되고, 상태를 알 수 없으면 255.

Reserved1
Reserved. must be zero

BatteryLifeTime
The number of seconds of battery life remaining, or -1 if remaining seconds are unknown.

BatteryFullLifeTime
The number of seconds of battery life when at full charge, or -1 if full battery lifetime is unknown.

참고 : MSDN
2008. 9. 5. 16:10

Windows Power management API - PBT_APMPOWERSTATUSCHANGE Event


Windows System에서 전력관리(Power management)를 위해 사용되는 API들이 있다. 지금 보게 될 'PBT_APMPOWERSTATUSCHANGE '라는 녀석도 그에 속한다.

'PBT_APMPOWERSTATUSCHANGE'는 사용하는 기계의 전원상태(power status)의 변화가 생길때 Windows system에서 어플리케이션에 전달(broadcast)되는 event 이다.
예를들어 노트북에서 AC전원을 사용하다가 전원코드를 뽑아서 배터리의 전원을 사용한다던지, 아님 그 반대든지.. 뭐 그런경우 시스템에서는 현재 사용하는 기계의 전원상태의 변화가 생김을 인지하고 이 이벤트를 날려준다(broadcasting).

이 이벤트는 'WM_POWERBROADCAST'라는 메시지를 통해서 어플리케이션에 전달되고, 해당하는 이벤트는 메시지의 'wParam'을 통해 전달된다.


사용방법은.. 대충 이렇다.
음.. Windows API를 예로들어 설명한다.(다른건 할줄몰라서.. 이것도.. 잘은.. -_-)

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;

    switch (iMessage) {
        ...
        case WM_POWERBROADCAST:
            switch(wParam){
            case PBT_APMPOWERSTATUSCHANGE:
                MessageBox(hWnd, TEXT("test"), TEXT("test"), MB_OK);
                return 0;
            }
        return 0;
        ...
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}


추가로 WM_POWERBROADCAST 메시지의 wParam은 다음과 같은 것들이 있다.

Event

Meaning

PBT_APMBATTERYLOW

Battery power is low

PBT_APMOEMEVENT

OEM-defined event occurred

PBT_APMPOWERSTATUSCHANGE

Power status has changed

PBT_APMQUERYSUSPEND

Request for permission to suspend

PBT_APMQUERYSUSPENDFAILED

Suspension request denied

PBT_APMRESUMEAUTOMATIC

Operation resuming automatically after event

PBT_APMRESUMECRITICAL

Operation resuming after critical suspension

PBT_APMRESUMESUSPEND

Operation resuming after suspension

PBT_APMSUSPEND

System is suspending operation


여기를 참고하면 될 듯 하다.
WM_POWERBROADCAST : http://msdn.microsoft.com/en-us/library/aa373247.aspx
PBT_APMPOWERSTATUSCHANGE : http://msdn.microsoft.com/en-us/library/aa372715(VS.85).aspx

2008. 8. 20. 10:52

GetCurrentDirectory()를 이용한 Windows에서 현재경로 받아오기..



Windows에서 현재 실행되는 프로그램의 현재 작업 디렉토리를 알아오기 위해 "GetCurrentDirectory()"를 사용한다.

첫번 째 인자로 경로를 표시할 문자열의 길이를 넣어주고, 두번 째 인자로 실제 받아온 경로를 보여준다.

간단히 예를 들면...
char Path[255];

GetCurrentDirectory(255, Path);
printf("Current Path is %s\n", Path);

이렇게 하면 콘솔창에서 현재 위의 프로그램의 경로를 확인할 수 있다.

MSDN을 검색하니 다음과 같이 되어있다.

GetCurrentDirectory Function

Retrieves the current directory for the current process.

Syntax

DWORD WINAPI GetCurrentDirectory(
__in DWORD nBufferLength,
__out LPTSTR lpBuffer
);

Parameters

nBufferLength [in]

The length of the buffer for the current directory string, in TCHARs. The buffer length must include room for a terminating null character.

lpBuffer [out]

A pointer to the buffer that receives the current directory string. This null-terminated string specifies the absolute path to the current directory.

To determine the required buffer size, set this parameter to NULL and the nBufferLength parameter to 0.

Return Value

If the function succeeds, the return value specifies the number of characters that are written to the buffer, not including the terminating null character.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

If the buffer that is pointed to by lpBuffer is not large enough, the return value specifies the required size of the buffer, in characters, including the null-terminating character.

Remarks

Each process has a single current directory that consists of two parts:

  • A disk designator that is either a drive letter followed by a colon, or a server name followed by a share name (\\servername\sharename)
  • A directory on the disk designator

To set the current directory, use the SetCurrentDirectory function.

In certain rare cases, if the specified directory is on the current drive, the function might omit the drive letter and colon from the path. Therefore, the size that is returned by the function might be two characters less than the size of the specified string, not including the terminating null character. This behavior might occur in edge situations such as in a services application. If you need the drive letter, make a subsequent call to GetFullPathName to retrieve the drive letter.

Examples

For an example, see Changing the Current Directory.

Requirements

Client Requires Windows Vista, Windows XP, or Windows 2000 Professional.
Server Requires Windows Server 2008, Windows Server 2003, or Windows 2000 Server.
Header

Declared in WinBase.h; include Windows.h.

Library

Use Kernel32.lib.

DLL

Requires Kernel32.dll.

Unicode/ANSI

Implemented as GetCurrentDirectoryW (Unicode) and GetCurrentDirectoryA (ANSI).



2008. 8. 19. 16:56

Windows 프로그램을 시작 프로그램으로 등록하기



MS Windows를 부팅할 때 자동으로 시작하는 프로그램을 볼 수 있다.
그리고 실제 자신이 작성한 프로그램도 그런 프로그램들 처럼 Windows가 시작할 때 자동으로 실행시킬 수 있다.

방법은 여러가지가 있다.

첫번 째는 가장 쉬운 방법으로 "시작 프로그램에 바로가기 복사"를 하는 방법이다.
"C:\Documents and Settings\사용자 폴더\시작 메뉴\프로그램\시작프로그램"에 자동으로 시작하기를 원하는 프로그램의 바로가기를 복사하면 된다.

두번 째는 "win.ini 파일에 등록"하는 방법이다.
"시작 -> 실행 -> sysedit" 를 실행 하여, 자동으로 실행하고자 하는 프로그램을 등록하면 된다.
load - Windows가 부팅할 때 자동으로 시작하는 프로그램을 등록한다.
run - load와 같이 자동  시작 프로그램을 등록한다.

세번 째는 "registry에 등록"하는 방법이다.
"HKEY_LOCAL_MACHINE의 Software\Microsoft\Windows\CurrentVersion\run"가 시작프로그램들이 위치하는 레지스트리의 위치이다. 이곳에 자동으로 시작하는 프로그램을 등록하면 된다.

아래와 같이 하면 자신이 작성하는 프로그램에 직접 소스코드를 넣어서 레지스트리에 등록하여 Windows가 실행 시 자동으로 실행하게 할 수도 있다.
#include <windows.h>
#include <assert.H>

bool cs_util_register_start_Prog  (const char*  sValue, const char*   sPath)
{
    HKEY hKey;
    DWORD dwDisp;
    DWORD dwSize;

   if( sValue == NULL || sPath == NULL)
   {
       return false;
    }
 
    assert(sValue != NULL);
    assert(sPath != NULL);

    if( RegCreateKeyEx (HKEY_LOCAL_MACHINE,
                                 "Software\\Microsoft\\Windows\\CurrentVersion\\run",
                                 0, NULL,REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
                                 NULL, &hKey, &dwDisp) != ERROR_SUCCESS)
    {
        if(hKey != NULL)RegCloseKey(hKey);
        return false;
    }
     dwSize = strlen(sPath);

    if( RegSetValueEx (hKey, sValue, 0, REG_SZ ,(LPBYTE)sPath, dwSize ) != ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return false;
    }

    RegCloseKey(hKey);
    RegFlushKey(hKey);

    return true;
}

....

void main()
{
    cs_util_register_start_Prog("레지스트리에 등록할 이름","등록할 프로그램의 경로");
    // ex) cs_util_register_start_Prog("test_program","c:\\test_program.exe");
    ....
}

대충 이렇게 해서 테스트 해보니.. 위의 루틴을 삽입한 프로그램을 한 번 실행 시키게 되면, 레지스트리에 위의 프로그램이 등록이 되더군...

대략 설치 파일에 이런 부분을 넣으면 편할 듯 하지만, 단순히 실행파일을 시작과 동시에 실행시키기엔 첫번 째 방법이 가장 쉽고 편할듯... ^^;

참고 : http://blog.naver.com/tija98?Redirect=Log&logNo=120037882771

2008. 8. 11. 15:18

GetMessage() 와 PeekMessage()



Windows API 프로그래밍에서 GetMessage()PeekMessage() 는 메시지 루프에서 사용되는 API이다. 둘다 메시지 큐에서 메시지를 가져오는 역할을 하는데.. 두 API에 약간의 차이는 있다.

BOOL GetMessage ( LPMSG lpMsg,
                            HWND hWnd,
                            UINT wMsgFilterMin,
                            UINT wMsgFilterMax)
GetMessage() 는 메시지 루프... 스레드 메시지 큐에서 메시지를 읽은 후 읽은 메시지를 큐에서 제거한다.

BOOL PeekMessage ( LPMSG lpMsg,
                              HWND hWnd,
                              UINT wMsgFilterMin,
                              UINT wMsgFilterMax,
                              UINT wRemoveMsg)

PeekMessage() 는 GetMessage() 와 마찬가지로 메시지 큐에서 메시지를 읽는 다 메시지의 범위를 줄 수 있는 기능도 GetMessage() 와 동일하다. 하지만, PeekMessage() 는 GetMessage() 와는 달리 읽은 메시지를 무조건 저거하지 않으며 큐가 비어있을 경우 대기하지 않고 바로 리턴한다는 점이 다르다. 따라서 이 함수는 메시지를 읽지 않고 단순히 메시지가 있는지 확인만 할 수 있으며, 이런 특성은 백그라운드 작업에 적절하다.
PeekMessage() 의 마지막 인자를 PM_NOREMOVE로 지정을 하면 큐에서 메시지를 없애지 않고 내용을 볼 수 있다. PM_REMOVE로 지정을 하면 GetMessage() 처럼 큐에서 메시지를 없앤다.


간단히 말해 GetMessage() 함수는 큐에 메시지를 받을 때 까지 복귀하지 않고 루프를 돌면서 대기하는 상태이지만, PeekMessage() 함수는 큐에 메시지가 없는 경우에도 즉석에서 제어를 돌려주고, 다른 일을 할 수 있다는 것이다.


출처 : http://winapi.co.kr

2008. 7. 31. 10:45

Windows Device Driver 관련 용어들..



갑작스레 디바이스 드라이버를 작성을 해야할 것 같아서.. 현재 열공(?)중이다...

아.. 솔직히 이런 저런일들로.. 아무것도 할 수 없을 것 같은 상태이긴 하지만.. 그래도 한다.. 꾸역꾸역..

아.. Windows Device에서 사요하는 용어는 몇가지가 있다. 그 중에서 기본이 되는 용어들 몇가지를 살펴보고자 한다.

  • DDK (Driver Development Kit)
  • VxD (Virtual Device Driver)
  • WDM (Windows Driver Model)
  • IFS (Installable File System)
  • WDF (Windows Driver Foundation)
  • WDK (Windows Driver Kit)


DDK

  - Windows 상에서 Device Driver를 개발하는 사람들이 꼭 사용해야할 모음(?) 정도로 생각하면 될 듯 하다.
    가장 기초가 되는, 뭐 이거 없으면 개발을 할 수 없는 뭐.. 그런것?? ntddk.h, wdm.h 등이 있다.

VxD
  - 가상 장치 관리자라고 불린다. x는 디바이스에서 키보드, 마우스 등을 나타낸다.
    Windows 95, 98, ME 등에서 사용을 하는 녀석이다.

WDM
  - windows NT 로 넘어오면서 통합된 Driver 의 필요에 의해 생성된 녀석이다. 일종의 Framework라고 생각하면 맞을 듯 하다.

WDF
  - Vista가 출시되면서 나오게 된 모델로, WDM 보다 조금 더 확장 된 개념으로 보면 된다.

IFS
  - 파일시스템 위주의 특화된 Kit 이라고 보면 된다. 파일시스템에는 CDFS, FASTFAT, NTFS 등이 있으며, ntifs.h를 사용해서 생성한다.

WDK
  - Windows 의 모든 드라이버를 말한다.
    기존의 DDK를 사용하였지만, 지금은 이녀석(WDK)를 사용하여 디바이스 드라이버를 작성하게 될것 같다.

아.. 대충 이리 용어라는걸 알아봤는데.. 도데체 디바이스 드라이버는 어찌 만드는 거지?? -_-;;


2008. 7. 28. 11:30

MSDN 키보드 입력 작동 방식 스크랩


키보드 입력 작동 방식

 

Windows Forms에서는 Windows 메시지에 대한 응답으로 키보드 이벤트를 발생시켜 키보드 입력을 처리합니다. 대부분의 Windows Forms 응용 프로그램에서는 키보드 이벤트를 처리하여 키보드 입력을 단독으로 처리합니다. 그러나 키가 컨트롤에 도달하기 전에 키를 가로채는 등의 고급 키보드 입력 시나리오를 구현하려면 키보드 메시지가 작동하는 방식을 알아야 합니다. 이 항목에서는 Windows Forms에서 인식하는 키 데이터 형식을 설명하고 키보드 메시지가 라우팅되는 방법에 대한 개요를 설명합니다. 키보드 이벤트에 대한 자세한 내용은 키보드 이벤트 사용을 참조하십시오.

 

키 형식

Windows Forms에서는 키보드 입력을 비트 Keys 열거형으로 나타내는 가상 키 코드로 식별합니다. Keys 열거형을 사용하면 눌려진 일련의 키를 결합하여 단일 값을 만들 수 있습니다. 이러한 값은 WM_KEYDOWN WM_SYSKEYDOWN Windows 메시지와 함께 제공되는 값에 해당합니다. KeyDown 또는 KeyUp 이벤트를 처리하여 실제로 눌려진 키를 대부분 감지할 수 있습니다. 문자 키는 Keys 열거형의 하위 집합이며 WM_CHAR WM_SYSCHAR Windows 메시지와 함께 제공되는 값에 해당합니다. 눌려진 키를 결합하여 문자가 만들어지는 경우에는 KeyPress 이벤트를 처리하여 해당 문자를 감지할 수 있습니다. 또는 Visual Basic 프로그래밍 인터페이스에서 노출되는 Keyboard를 사용하여 눌려진 키를 확인하고 키를 보낼 수 있습니다. 자세한 내용은 키보드에 액세스를 참조하십시오.

 

키보드 이벤트의 순서

앞에서 설명한 대로 한 컨트롤에서 발생할 수 있는 키보드 관련 이벤트는 세 가지입니다. 다음 시퀀스는 키보드 이벤트의 일반적인 순서를 보여 줍니다.

  • 사용자가 "a" 키를 누르면 해당 키가 전처리되고 디스패치된 다음 KeyDown 이벤트가 발생합니다.

  • 사용자가 "a" 키를 누르고 있으면 해당 키가 전처리되고 디스패치된 다음 KeyPress 이벤트가 발생합니다.

  • 이 이벤트는 사용자가 키를 누르고 있을 때 여러 차례 발생합니다.

  • 사용자가 "a" 키를 놓으면 해당 키가 전처리되고 디스패치된 다음 KeyUp 이벤트가 발생합니다.

 

키 전처리

다른 메시지와 마찬가지로 키보드 메시지는 폼이나 컨트롤의 WndProc 메서드에서 처리됩니다. 그러나 키보드 메시지를 처리하기 전에 PreProcessMessage 메서드는 특수 문자 키와 실제 키를 처리하도록 재정의할 수 있는 메서드를 하나 이상 호출합니다. 이러한 메서드를 재정의하여 컨트롤에서 메시지를 처리하기 전에 특정 키를 감지하고 필터링할 수 있습니다. 다음 표에서는 수행할 작업과 발생하는 관련 메서드를 메서드 발생 순서에 따라 보여 줍니다.

 

KeyDown 이벤트의 전처리

작업

관련 메서드

설명

액셀러레이터 키나 메뉴 바로 가기 같은 명령 키를 확인합니다.

ProcessCmdKey

이 메서드는 일반 키보다 우선되는 명령 키를 처리합니다. 이 메서드가 true를 반환하는 경우 키 메시지가 디스패치되지 않고 키 이벤트도 발생하지 않습니다. false를 반환하는 경우에는 IsInputKey가 호출됩니다.

전처리가 필요한 특수 키인지 아니면 KeyDown 이벤트를 발생시켜 컨트롤에 디스패치해야 하는 일반 문자인지 여부를 확인합니다.

IsInputKey

이 메서드가 true를 반환하는 경우에는 컨트롤이 일반 문자이고 KeyDown 이벤트가 발생합니다. false를 반환하는 경우에는 ProcessDialogKey가 호출됩니다.

Note참고

컨트롤에서 키나 키 조합을 받도록 하려면 PreviewKeyDown 이벤트를 처리한 다음 원하는 키나 키 조합에 대해 PreviewKeyDownEventArgsIsInputKeytrue로 설정합니다.

키가 탐색 키(Esc, Tab, Enter 또는 화살표 키)인지 여부를 확인합니다.

ProcessDialogKey

이 메서드는 컨트롤 내에서 컨트롤과 부모 컨트롤 간의 포커스 전환과 같은 특수 기능을 담당하는 실제 키를 처리합니다. 현재 컨트롤에서 키를 처리하지 않으면 ProcessDialogKey가 부모 컨트롤에서 호출되고 계층 구조의 최상위 컨트롤에까지 이같은 호출 방식이 적용됩니다. 이 메서드에서 true를 반환하면 전처리는 완료되지만 키 이벤트는 생성되지 않습니다. false를 반환하면 KeyDown 이벤트가 발생합니다.

 

KeyPress 이벤트의 전처리

작업

관련 메서드

설명

키가 컨트롤에서 전처리 되어야 하는 일반 문자인지 여부를 확인합니다.

IsInputChar

문자가 일반 문자인 경우 이 메서드는 true를 반환하고 KeyPress 이벤트가 발생하지만 추가적인 전처리 작업은 발생하지 않습니다. 일반 문자가 아닌 경우에는 ProcessDialogChar가 호출됩니다.

문자가 단추의 &OK와 같은 니모닉인지 여부를 확인 합니다.

ProcessDialogChar

이 메서드는 ProcessDialogKey와 비슷하게 컨트롤 계층 구조를 올라가며 호출됩니다. 컨트롤이 컨테이너 컨트롤인 경우 이 메서드는 컨트롤과 그 자식 컨트롤에 대해 ProcessMnemonic을 호출하여 니모닉을 확인합니다. ProcessDialogChartrue를 반환하는 경우 KeyPress 이벤트가 발생하지 않습니다.

 

키보드 메시지 전처리

폼이나 컨트롤의 WndProc 메서드에 도달한 키보드 메시지는 재정의할 수 있는 메서드 집합에 의해 처리됩니다. 이러한 메서드는 각각 키보드 메시지가 처리되어 컨트롤에서 사용되었는지 여부를 지정하는 Boolean 값을 반환합니다. 이러한 메서드 중 한 메서드에서 true가 반환되면 해당 메시지가 처리된 것으로 간주되므로 추가 처리를 위해 컨트롤의 기본 또는 부모에 메시지가 전달되지 않습니다. 그렇지 않은 경우에는 메시지가 메시지 큐에 유지되고 컨트롤의 기본 또는 부모의 다른 메서드에서 처리됩니다. 다음 표에서는 키보드 메시지를 처리하는 메서드를 보여 줍니다.

메서드

설명

ProcessKeyMessage

이 메서드는 컨트롤의 WndProc 메서드에서 받은 모든 키보드 메시지를 처리합니다.

ProcessKeyPreview

이 메서드는 키보드 메시지를 컨트롤의 부모에게 보냅니다. ProcessKeyPreviewtrue를 반환하면 키 이벤트가 생성되지 않고, 그렇지 않은 경우에는 ProcessKeyEventArgs가 호출됩니다.

ProcessKeyEventArgs

이 메서드는 KeyDown, KeyPress KeyUp 이벤트를 적절하게 발생시킵니다.

 

키보드 메서드 재정의

키보드 메시지를 전처리하고 처리할 때 재정의할 수 있는 여러 가지 메서드가 있지만 그 중 다음과 같은 메서드가 특히 많이 사용됩니다. 다음 표에서는 수행할 작업과 키보드 메서드를 재정의할 수 있는 가장 좋은 방법을 보여 줍니다.

작업

메서드

탐색 키를 가로채고 KeyDown 이벤트를 발생시킵니다. 예를 들어 Tab 키와 Enter 키를 텍스트 상자에서 처리해야 할 수 있습니다.

IsInputKey를 재정의합니다.

컨트롤에서 특수 입력 키나 탐색 키에 대한 처리를 수행합니다. 예를 들어, 목록 컨트롤에서 화살표 키를 사용하여 선택한 항목을 변경할 수 있습니다.

ProcessDialogKey를 재정의합니다.

탐색 키를 가로채고 KeyPress 이벤트를 발생시킵니다. 예를 들어, 스핀 상자 컨트롤에서 화살표 키를 여러 차례 눌러 항목 전체를 빠르게 진행할 수 있습니다.

IsInputChar를 재정의합니다.

KeyPress 이벤트 중 특수 입력 키나 탐색 키에 대한 처리를 수행합니다. 예를 들어, 목록 컨트롤에서 "r" 키를 누른 채로 r 문자로 시작하는 항목 사이를 건너뛸 수 있습니다.

ProcessDialogChar를 재정의합니다.

사용자 지정 니모닉 처리를 수행합니다. 예를 들어, 도구 모음에 포함된 소유자가 그린 단추의 니모닉을 처리할 수 있습니다.

ProcessMnemonic를 재정의합니다.

 

참고 항목

참조

My.Computer.Keyboard 개체
Keys
WndProc
PreProcessMessage

개념

키보드에 액세스
키보드 이벤트 사용

 


2008. 7. 24. 15:47

키보드 키의 상태값을 알아오기



키보드 관련된 작업을 Windows XP 에서 프로그래밍을 하고 있는 중이다.
아... 'OS' 관련 작업하다가 갑자기 몇년만에 'Windows Application' 작업을 하려니 적응이 안된다.
어찌 됐건 해야 하는 일이므로.. 이리 저리 자료를 찾고 있는 중이긴 하지만.. 빡쎄다... -_-

키보드 키의 상태값을 받아오는 방법에 대해 찾고 있던 도중 'Windows API'에 좋은 함수가 있다는 걸 알아버렸다.ㅋ

GetKeyState() 라는 함수인데.. 이녀석은 키가 눌린 상태인지.. 그리고 키가 토글상태가 무엇인지를 알아낼때 사용되는 함수이다.
쉽게 말해서 NumLock키의 경우 토글된 상태이면 NumLock LED에 불이 들어온다. 토글된 상태가 아니면 NumLock LED의 불이 꺼진다. 이런 상태를 받아오는 것이다.
이 함수는 다음과 같다.
SHORT GetKeyState(      
    int nVirtKey
);
parameter는 상태를 알고자하는 키의 Virtual Key값을 넣으면 되고, Return 되는 값은 상태를 알고자하는 Virtual Key값의 상태를 리턴한다.

쉽게 예를 들면, 음.. NumLock 키가 눌려져 있는지를 보려면.. 다음과 같이 해주면 될 것이다.
 
       int numlock_status = 0;

        ....

        if((::GetKeyState(VK_NUMLOCK) & 0x80000 ) > 0)
            numlock_status = 1;
        else
            numlock_status = 0;

이와 유사한 기능을 가지고 있는 함수로.. GetAsyncKeyState() 라는 함수가 있다.

MSDN에는 현재 하드웨어(키보드)의 상태값을 알아내고자 한다면.. GetAsyncKeyState() 를 사용하라고 한다.
GetKeyState() 는 메시지큐에 저장된 메시지에 따라 값이 변하기 때문이다. 메시지큐에 처리되지 않은 CTRL 키가 눌렸다는 메시지가 쌓여있을 때, 사용자가 CTRL 키를 더이상 누르지 않고 있다면... GetAsyncKeyState() 는 "키가 눌려있지 않음"을 반환하고, GetKeyState() 는 "키가 눌렸음"을 반환하기 때문이다.
(참고 : 러브러브 님의 블로그)

2008. 4. 24. 21:42

CVI Control Modes for Generating Events



CVI로 이런 저런 프로그래밍을 하는 도중 늘 궁금한게 하나 있었다.
말이 그렇지 하나 뿐만이 아니고 아주 아주 많이있다..... -_-

그러던 도중 오늘 드디어 궁금증을 하나 풀어낸 것이 있으니..  바로 "컨트롤 모드(control mode)"에 관련된 것이다.
각 컨트롤마다 Edit 창을 열어 속성을 정하거나 하는데.. 중간에 보면 꼭 Control Mode라는 것이 있는 것이다. 내용도 'Hot', 'Normal', Indicator', 'Validate'등 다양하게 있는데 뭔뜻인지.. ^^;

CVI정보나눔의 질문답변란에서 그 정답을 찾았다.

> 안녕하세요...
> cvi를 시작한지 얼마 안 된 학생 입니다.
> hot와 validate의 차이점에 관해 좀 알려 주시면 감사 하겠습니다.
> 수고하세요...
>

CVI 도움말의 다음 항목에서 잘 설명해 주고 있습니다.
Control Modes for Generating Events

아래는 제가 공부삼아 번역해본 내용입니다.

---------------------------------------------------------
이벤트 발생에 대한 Control Mode

여러분은 control에 의해 발생되는 이벤트의 type을 match시키기 위해 control의 mode를 Normal, Indicator, Hot 혹은 Validate mode로 설정할 수 있습니다.

- Value Changed event는 GUI의 사용자가 control의 설정값을 수정할 때 발생되는 이벤트입니다. 즉, slide control의 slider를 마우스로 드래그 한다든지, string control에다 문자를 입력할 때 발생됩니다.

- Commit event는 GUI의 사용자가 동작을 실제로 완료할 때 발생됩니다. 즉, menu를 선택한다든지, 숫자를 입력하고 Enter키를 누른다든지, 혹은 slide control에서 slider를 드래그한 후에 마우스 버튼을 놓을 때 말입니다.

여러분이 control을 만들 때, 아래의 control mode 중에서 하나를 지정할 수 있습니다.
control mode는 control이 이벤트를 어떻게 발생시킬지, 사용자가 조작할 수 있는 범위를 어떻게 정할지를 결정합니다.

- Normal: 이 모드에서는 사용자가 control을 조작할 수 있게 하고, 또 control이 commit 이벤트를 제외한 모든 이벤트를 발생시킬 수 있습니다.

- Indicator: 이 모드에서는 사용자가 control을 조작할 수가 없고, 또 control이 commit나 value changed event를 발생시키지 않습니다.

- Hot: 보통 Default로 설정되어 있습니다. 이 모드는 Normal과 거의 같은데, 사용자가 어떤 동작을 수행했을 때, control이 commit 이벤트를 발생시킵니다. 통상적으로 hot control은 상태가 변경되었을 때 commit event를 발생합니다. 예를 들면, 사용자가 binary switch를 off에서 on으로 드래그하고, 마우스 버튼을 놓으면, commit event가 발생됩니다. 아래의 control type에 대한 설명은 commit event가 어떻게 발생되는지에 대해 확실한 규칙을 보여줍니다.

   o Hot numeric, string, 그리고 text box control은 값을 control에 입력한 후, Enter나 Tab을 눌렀을 때,
     또는 값을 입력한 후 마우스를 다른 곳 아무데나 클릭했을 때, commit event를 발생합니다.

   o Hot list box control은 check mode가 아닐 때, 사용자가 control이 active 되어 있는 동안 Enter를 누른
     다든지, list item을 더블클릭했을 때 commit event를 발생합니다.

   o Hot list box control은 check mode일 때, 사용자가 control이 active되어 있는 동안 스페이스바를 누른
     다거나, list item을 더블클릭했을 때 commit event를 발생합니다.

   o Hot graph control은 사용자가 화살표 키와 함께 커서를 이동할 때나, 사용자가 커서를 옮긴 후에 마우
     스 버튼을 놓으면, commit event를 발생시킵니다.

   o Hot table control은 사용자가 numeric 혹은 string cell에다 값을 입력한 후 active cell을 변경할 때,
     commit event를 발생시킵니다.

- Validate: 이 모드는 Hot 모드와 한가지 점만 빼고는 동일합니다.
commit event가 발생되기 전에 프로그램은 range-checking 속성이 Notify로 되어 있는 panel상의 모든 numeric control을 유효화(validate)시키게 됩니다. Notify 설정은 LabWindows/CVI가 미리 지정된 range를 벗어나는 control값을 체크하도록 합니다. 만약 range를 벗어나는 무효한 조건이 발견된다면, LabWindows/CVI는 control을 활성화시키고, Out of Range 라는 이름의 notification box를 표시합니다. 그리고, validate control은 사용자가 모든 control에 대해 유효한 새 값을 입력할 때까지는 commit event를 발생시키지 않습니다.
이런 과정은 GUI가 commit event를 발생시키기 전에 모든 numeric/scalar control의 값을 유효한지를 분명하게 해줍니다.
---------------------------------------------------------

쉽게 말해서,
Hot control은 숫자 컨트롤의 값이 range를 벗어나더라도 commit event가 발생되는 것이고,

Validate control은 숫자 컨트롤의 값이 range를 벗어나면,
유효한 새 값이 입력되기 전까지 commit event가 발생되지 않는 모드입니다. 즉, 숫자 컨트롤에 range를 설정한다면, Validate 모드로 하는 것이 더 적절하겠습니다.

그럼, 좋은 하루되세요.
2003-02-13 18:49:09
출처 : CVI 정보나눔(질문답변 게시판)

헐... 2003년 게시글이다... -_-
오래도 됐건만.. 난 이제서야 이런걸 찾고 하고 있다네.. ㅋㅋ

위의 내용은 'LabWindows/CVI Help'에서 'Control Modes for Generating Event(Library Reference > User Interface > Using a Graphical User > Control Modes for Generating Event)'라는 이름으로 찾을 수 있다.

'Programmings > CVI' 카테고리의 다른 글

CVI Serial통신 관련 함수  (0) 2008.04.21
CVI 시리얼 통신 예제  (0) 2008.04.16
CVI Ring control의 간단한 예  (0) 2008.04.11
CVI에서 Dynamic Link Library(DLL) 만들기  (0) 2008.02.01
CVI에서 Static Library 만들기  (0) 2008.02.01