'Programmings'에 해당되는 글 51건

  1. 2009.03.03 아스키 코드표
  2. 2009.02.05 프로그램 실행 에러 - MFC71D.DLL을(를) 찾을 수 없으므로... 5
  3. 2009.01.19 MFC42D.DLL 을 찾을 수 없다라는 메시지 창이 뜰 때.. 22
  4. 2008.10.01 Windows API 메시지 데드록(DeadLock) 관련 함수 1
  5. 2008.10.01 노트북의 배터리 정보를 받아오자
  6. 2008.09.22 error C2664: 'CreateFileW' : cannot convert parameter 1 from 'const char [9]' to 'LPCWSTR'
  7. 2008.09.19 하드디스크 용량 가져오기
  8. 2008.09.19 윈도우를 투명하게!!! 1
  9. 2008.09.11 Windows Power Scheme Management APIs
  10. 2008.09.11 Windows Power Management Structures
2009. 3. 3. 14:59

아스키 코드표



문자열 작업을 하다 보면 가끔 필요할 때가 있는데.. 그때마다 웹에서 아스키 코드 검색하는것두 꽤 귀찮다.
그냥 여기에 올려놓고 필요할 때 볼려구... ^^;

아스키 코드표

2009. 2. 5. 10:14

프로그램 실행 에러 - MFC71D.DLL을(를) 찾을 수 없으므로...



프로그램을 실행하다보면 간혹 다음과 같은 에러 메시지를 볼 때가 있다.
"MFC71D.DLL을(를) 찾을 수 없으므로 응용 프로그램을 시작하지 못했습니다. 이문제를 해결하려면 응용 프로그램을 다시 설치하십시오.

이는 MFC로 작성된 프로그램을 실행 시킬 때 필요로 하는 MFC71D.DLL이라는 파일이 없어서 발생하는 문제이다.이 때는 단순히 MFC71D.DLL 이라는 파일을 구해서 실행하는 파일이 있는 폴더 혹은 WINDOWS(C:\WINDOWS)폴더 혹은 System(C:\WINDOWS\System32)폴더에 복사한 후 해당 프로그램을 실행하면 된다.

위와 같이 다양한 경로에 MFC71D.DLL 파일을 넣어도 정상적으로 동작하는 이유는 해당 프로그램이 실행될 때 연관된 파일을 찾는 순서가 정해져 있어서 여기 저기 필요한 곳을 뒤져 필요한 파일을 찾아서 실행하기 때문이다.
  1. 프로그램의 실행파일이 존재하는 디렉토리
  2. Windows System(C:\WINDOWS\System32) 디렉토리
  3. Windows(C:\WINDOWS) 디렉토리
  4. 환경변수 PATH에 의해 지정된 디렉토리
MFC71D.DLL 파일을 넣은 뒤 응용 프로그램을 다시 실행하면 한번 더 에러 메시지를 볼 수 있다.
"MSVCR71D.DLL을(를) 찾을 수 없으므로 응용 프로그램을 시작하지 못했습니다. 이 문제를 해결하려면 응용 프로그램을 다시 설치하십시오."

이녀석도 마찬가지로 MSVCR71D.DLL을 MFC71D.DLL과 같은 방식으로 해주면 해결을 할 수가 있다.

이렇게 하고 다시 프로그램을 실행시키면 정상적으로 프로그램이 실행되는 것을 확인할 수 있을 것이다.

2009. 1. 19. 19:00

MFC42D.DLL 을 찾을 수 없다라는 메시지 창이 뜰 때..



가끔 MFC 응용 프로그램을 실행하다 보면 "MFC42D.DLL을(를) 찾을 수 없으므로 응용 프로그램을 시작하지 못했습니다. 이 문제를 해결하려면 응용 프로그램을 다시 설치하십시오"라는 메시지 창을 볼 기회가 있다.

아무래도 실행시키는 컴퓨터에 MFC 관련 라이브러리가 없어서 그러는 모양인지..
일반적인 릴리즈 버전의 MFC 프로그램의 경우 윈도우 설치시 설치가 되지만, 디버그용으로 배포된 MFC 프로그램을 실행할 경우 몇몇 라이브러리가 없어서 실행이 되질 않는 경우가 있다고 한다.
본인 컴퓨터에는 Visual Studio 2005가 설치된 상황인데.. Visual Studio 6.0 관련 라이브러리인가? -_-;;
VS 6.0으로 제작된 MFC 프로그램을 실행할 때 발생했던 메시지 창이라서.... ^^;

일단 이리 저리 자료를 찾다가 몇몇 필요한 파일이있다는 것을 알아버렸다!!
  • MFC42D.DLL
  • MFCO42D.DLL
  • MSVCRTD.DLL
  • MSVCP60D.DLL

이녀석을을 구해서 C:\WINDOWS 폴더 혹은 C:\WINDOWS\system32 폴더에 복사를 해주면 정상적으로 프로그램이 실행된다.

검색을 해보면 이리저리 쉽게 구할 수 있는 파일들이지만.. 혹시나 구하기 힘들다거나 검색했는데 이 페이지가 검색된 사람은 아래 압축파일을 사용해도 무관하지만.. 그래도 의심이 많은 사람은 안써도 상관 없음!! ㅋ


2008. 10. 1. 18:02

Windows API 메시지 데드록(DeadLock) 관련 함수


'SendMessage()'라는 함수를 통해서 프로그래머는 일종의 사용자 메시지를만들 수 있다.
같은 스레드 내에서 이 함수를 사용할 경우에는 크게 문제 될 것이 없지만, 다른 스레드로 SendMessage()를 사용해 메시지를 날리게 될 경우 상당히 좋지않은 결과를 초래할 수도 있다.

SendMessage() 함수는 메시지를 받은 윈도우 프로시저가 리턴하기 전까지는 리턴하지 않기 때문에, 다른 스레드로 메시지를 날리게 될 경우 그 스레드에서 리턴하지 않는 한 SendMessage()를 한 스레드는 홀드되는 상태로 남게 된다. '데드록(DeadLock)'가 되는 것이다.

이를 해결하는 방법으로 여러가지가 있겠지만, 간단히 몇가지를 살펴보면 다음과 같다.
'InSendMessage()''ReplyMessage()'를 이용하여 SendMessage()로 부터 받은 메시지를 처리하는 부분이다.
if(InSendMessage())             // 다른 스레드로부터 메시지가 들어왔는지 확인
    ReplyMessage(TRUE);      // SendMessage() 로부터 전달된 메시지를 바로 리턴한다.

위와 같은 처리를 해주면, SendMessage()를 호출한 윈도우는 리턴되지 않더라도 즉시 다른 일을 할 수 있다.

다른 방법으로는 SendMessage()를 이용하지 않고 다음의 함수를 사용하는 방법이다.
BOOL SendNotifyMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
LRESULT SendMessageTimeout( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam,              
                                                UINT fuFlags, UINT uTimeout, PDWORD_PTR lpdwResult );

'SendNotifyMessage()' 함수는 SendMessage()와 유사하지만, hWnd 가 다른 스레드의 윈도우일 경우 대기를 하지 않고 즉시 리턴하는 함수이다.
'SendMessageTimeout()' 함수는 지정한 시간이 지나면 메시지의 처리 여부와 상관없이 즉시 리턴함으로 메시지를 보낸 윈도우가 홀드되는 것을 막는다.


2008. 10. 1. 12:03

노트북의 배터리 정보를 받아오자


10월의 첫날부터... 이런 상투적인 업무 포스트밖에 올릴 것이 없다는게 참 슬프긴 하지만.. 그리도.. 머.. -_-;;

노트북의 배터리의 정보를 받아오는 부분에 대해서 뭔가를 하고 있다. 배터리의 용량, Voltage, 상태... 뭐 그밖의 등등..  검색을 하던중.. 좋은 정보를 얻어 포스팅 한다.
MSDN에서 검색을 했는데 'Enumerating Battery Devices'라고 꽤 쓸만한 예제 소스가 있었다.
여기(http://msdn.microsoft.com/en-us/library/bb204769(VS.85).aspx )를 클릭하면 정보를 얻을 수 있다.

이녀석을 바로 적용하면 동작하지는 않고 몇가지 수정을 해주어야 한다.
VS2005환경에서 Win32 API를 이용하여 테스트 프로그램을 작성하였다.

일단 필요한 헤더 파일('BatClass.h', 'Setupapi.h')을 적당한 위치에 넣어(#include)준다.
BatClass.h는 배터리에 관련된 것들을 정의해 놓은 헤더파일이고, Setupapi.h는 'SetupDiGetClassDevs', 'SetupDiEnumDeviceInterfaces', .. 등과 같은 함수들을 정의해 놓은 헤더파일이다.

헤더파일을 추가하고 컴파일을 하게 되면 에러가 뜰것이다. 안뜰지도 모르지만.. 본인의 경우에는 에러가 있었다.
HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT |                                                                DIGCF_DEVICEINTERFACE);
위의 위치에서 'GUID_DEVCLASS_BATTERY' 라는 녀석이 정의되지 않아 찾을 수 없다고...

BatClass.h라는 파일을 찾아서 열어본다.
이런 저런 코드들이 보일텐데.. GUID_DEVCLASS_BATTERY를 검색해보면 없을 거이다. GUID_DEVCLASS_BATTERY를 추가시켜주어야 한다.
코드를 대충 보면 비슷한 녀석들이 모여있는 곳이 있다. 그곳에 다음을 넣어준다.
...
DEFINE_GUID( GUID_DEVCLASS_BATTERY,
                      0x72631E54, 0x78A4, 0x11D0, 0xBC, 0xF7, 0x00, 0xAA, 0x00, 0xB7, 0xB3, 0x2A);
...

구글에서 검색하다 찾았는데.. 위의 문장이 정의된 GUID_DEVCLASS_BATTERY 의 값인듯 하다.

이렇게 수정을 하고 컴파일을 다시 하면, 정상적으로 빌드가 될 것이고, 추가로 필요한 배터리의 정보는 소스의 내용을 수정해서 얻을 수 있을 것이다.

소스는 분석을 해봐야 더 정확한 것을 알 수 있을 듯한데.. 배터리 뿐만 아니라 여러 디바이스 드라이버의 정보를얻을 때에도 유용하게 쓰이는 듯 보인다.



2008. 9. 22. 10:34

error C2664: 'CreateFileW' : cannot convert parameter 1 from 'const char [9]' to 'LPCWSTR'


VS2005를 사용하면서 'error C2664: 'CreateFileW' : cannot convert parameter 1 from 'const char [9]' to 'LPCWSTR''라는 에러 메시지를 종종 보게 된다.

CreateFile()라는 함수를 사용할 때 첫번째 인자의 형식이 잘못된듯한데.. 지금 사용하고 있는 CreateFile()라는 녀석을 보면 CreateFile("aaa.txt",GENERIC_READ,0,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)로 문자열을 처리하는 부분이다.
"aaa.txt"라는 문자열을 사용하고 있었는데.. 이를 TEXT("aaa.txt")라든지 L"aaa.txt"로 바꾸어주면 에러가 발생하지 않는다.

하지만.. 다른 문제가 발생해 버렸다. 메지시 박스로 테스트 문자열을 출력하는데 다음과 같이 문자열이 깨져나오는 현상이 발생을 한 것이다.

이 부분을 해결하기 위해서는 문자 집합(Character Set)의 설정을 바꾸어 주어야 하는 모양이다.
VS2005의 메뉴에서 Project->Properties...(Alt+F7)을 선택하여 해당 프로젝트의 프로퍼티 창을 연다. 왼쪽의 항목을 보여주는 창에서 Configuration Properties의 General에서 Character Set 항목을 살펴본다. 기본적으로 VS2005에서는 Character Set이 'Use Unicode Character Set'으로 되어 있는 듯 하다. 이녀석의 세팅을 'Use Multi-Byte Character Set'으로 수정을 한다.

다시 컴파일을 한 뒤 실행을 시키면 원하는 결과를 얻을 수 있을 것이다.

한결 보기 좋아졌다... 아니 많이 보기 좋아졌네..

간단한 것인데.. 툴에 대해 모르는 것이 너무 많아 고생을 많이 하는 부분중에 하나인 듯 하다.

2008. 9. 19. 19:05

하드디스크 용량 가져오기


GetDiskFreeSpaceEx() 라는 함수가 하드디스크의 총 용량, 사용 용량, 남은 용량을 가져오는 함수이다.

MSDN을 살펴보면 다음과 같이 함수가 정의되어 있다.
BOOL WINAPI GetDiskFreeSpaceEx(
  __in LPCTSTR lpDirectoryName,
  __out PULARGE_INTEGER lpFreeBytesAvailable,
  __out PULARGE_INTEGER lpTotalNumberOfByte,
  __out PULARGE_INTEGER lpTotalNumberOfFreeBytes
);

사용법은 직관적으로 함수의 인자를 보면 알 수 있을 것이다.
첫 번째 인자에 원하는 파티션의 경로(c:\, d:\ 등의)를 넣어준다. 그러면 나머지 인자에서 원하는 정보를 얻을 수 있다.

간단한 예제를 가지고 사용하는 방법을 알아본다. 나중에 필요할 때 대충 참고할 요령으로.. ^^;

ULARGE_INTEGER avail, total, free;
avail.QuadPart = 0L;
total.QuadPart = 0L;
free.QuadPart = 0L;
int m_avail, m_total, m_free;
TCHAR buf[125];

// C:\의 하드디스크 용량 정보를 받아올 것이다.
GetDiskFreeSpaceEx(TEXT("c:\\"), &avail, &total, &free);

// GByte 로 표현을 하기 위한 부분.. MByte는 숫자가 너무커서... -_-;
m_total = (int)(total.QuadPart>>30);
m_free = (int)(free.QuadPart>>30);

// 간단하게 메시지 박스로 출력을 해서 확인한다.
wsprintf(buf, TEXT("실제용량 %d GByte, 남은용량 %d GByte"), m_total, m_free);
MessageBox(hWnd, buf, TEXT("test"), MB_OK);
참고로 MByte 단위로 하드디스크의 용량을 계산하고자 한다면 아래와 같이 수정을 해주면 된다.
m_total = (int)(total.QuadPart >> 20);
m_free = (int)(free.QuadPart >> 20);

2008. 9. 19. 11:14

윈도우를 투명하게!!!


프로그램을 하다보면 이런 저런 황당한 요구사항을 많이 겪게 된다. 가령 현재 실행되는 윈도우를 약간 투명하게 해서 그 프로그램 아래 있는 다른 것들을 볼 수 있도록 해달라는..

대충 알송의 데스크톱 가사보기와 같은 그런 걸 원하는 모양이다.

아.. 저런건 어찌 만들지...-_- 하면서 이리 저리 검색을 해본 결과.. 가능한 것이었고.. 간단한 테스트 프로그램을 통해 원하는 결과를 대충 얻어 포스팅 한다.

현재 사용하는 툴은 VS2005이고, Windows API로 작성이 되었다.

투명한 윈도우를 만들기 위해서는 SetLayeredWindowAttributes() 라는 함수를 사용해야 한다. 이녀석은 Layered Window 의 투명도 / 색상 등을 설정할 수 있는 함수이다.
BOOL SetLayeredWindowAttributes(  
    HWND hwnd,            - 투명하게 처리할 윈도우의 핸들
    COLORREF crKey,    - 대상 윈도우의 투명하게 처리할 색상(COLORREF)값
    BYTE bAlpha,           - 대상 윈도우의 투명도를 설정 ( 0 ~ 255)
    DWORD dwFlags       -  LWA_COLORKEY, LWA_ALPHA 등의 옵션
);

이 함수를 사용하기 위해서는 'Windows 2000 이상의 운영체제'여야 하고, 'Windows.h 헤더파일을 포함'하고 'User32.lib 라는 라이브러리를 사용'해야 한다. 뭐 요즘 사용하는 운영체제는 거의 XP 이상일 것이고, 윈도우즈 프로그램을 하면 기본적으로 Windows.h 와 User32.lib는 사용할 것이니.. 별로 신경을 안써도 될 듯하다.

추가로 신경을 써야 할 부분은 #include <windows.h> 위에 추가시켜 줘야 하는 부분이 있다는 것이다.

 #define WINVER 0x500  
 #define _WIN32_WINNT 0x500 
 #include <windows.h>

위와 같이 처리해주는 부분이 있어야 하는 이유는... 윈도우즈 프로그램에서는 윈도우즈 버전에 따라 사용 혹은 사용할 수 없는 함수들이 있다고 한다. Winodws 2000 이상에서만 사용되는 함수를 사용하기 위해서는 위와같이 처리해주어야 한다. 그렇지 않으면 에러가 발생할지도... ^^;

CreateWindowsEX()를 사용해 윈도우즈를 생성할 때 WS_EX_LAYERED라는 속성을 넣어준다.
아니면, 윈도우즈 생성시기가 아닌 나중에라도

SetWindowLong ( hDlg, GWL_EXSTYLE, GetWindowLong(hDlg, GWL_EXSTYLE) | WS_EX_LAYERED );
를 쓰던지 해서 이녀석을 넣어줘야 정상적으로 투명 윈도우를 만들어낼 수 있다.

마지막으로 SetLayeredWindowAttributes() 함수를 사용한다. 이 함수의 네번 째 인자는 LWA_ALPHA를 사용하고, 세번째 인자의 값을 조절하면서 투명도를 조절하면 된다.

SetLayeredWindowAttributes(hDlg, 0, 100, LWA_ALPHA);
이렇게 처리를 해주면...
사용자 삽입 이미지

사용자 삽입 이미지
이렇게 변한다고... ㅋ


음.. 조금 신기해 주는데.. ㅋㅋ

2008. 9. 11. 15:20

Windows Power Scheme Management APIs



Windows system 에서 Power Scneme 을 관리하는 API들이다.

음.. 관리라...
일단 존재하지 않는 power scheme을 생성할 수 있을 것이고, 생성되어 있는 power shceme의 정보를 가져오거나 업데이트 할 수 있을 것이고.. 현재 사용되고 있는 power의 정보(데이터, GUID)등을 가져오고나 업데이트 할 수 있을것이고, 마지막으로 존재하는 맘에 들지 않는 power scheme을 제거할 수 있는 등..
뭐 그런것들이 있을것이다.
이런 일들을 하는 API들을 알아본다.


다음과 같은 APIs 를 이용하여 Power Scheme 을 관리할 수 있다.
GetActivePwrScheme() - 현재 사용중인(활성화 된) power scheme의 index를 가져온다.
GetCurrentPowerPolicies() - 현재 사용중인(활성화 된) power shceme의 setting 정보를 가져온다.
SetActivePwrScheme() - 현재 사용중인(활성화 된) power scheme의 setting을 바꾼다.
WritePwrScheme() - 새로운 power scheme 을 생성한다. 이녀석을 적용시키려면 반드시 SetActivePwrScheme()를 사용해야 한다.
DeletePwrScheme() - 존재하는 power scheme 중 원하는 녀석을 삭제한다.

추가로.. scheme을 업데이트 하는 녀석들은 다음과 같다.
WritePwrScheme(), WriteGlobalPwrPolicy(), WritePorcessorPwrScheme()
그리고 이를 적용시키기 위해서는 SetActivePwrScheme() 를 사용해줘야 한다.

용도에 맞게 골라서 사용을 자~알하면 된다.


2008. 9. 11. 10:48

Windows Power Management Structures


Windows system의 API가 제공하는 Power Management관련 structures(구조체)에 대해서 이야기 해보려 한다.

Windows system의 전력관리에 사용되는 구조체들은 다음과 같다.
ADMINISTRATOR_POWER_POLICY
BATTERY_INFORMATION
BATTERY_MANUFACTURE_DATE
BATTERY_QUERY_INFORMATION
BATTERY_REPORTING_SCALE
BATTERY_SET_INFORMATION
BATTERY_STATUS
BATTERY_WAIT_STATUS
DISPLAY_BRIGHTNESS
GLOBAL_MACHINE_POWER_POLICY
GLOBAL_POWER_POLICY
GLOBAL_USER_POWER_POLICY
MACHINE_POWER_POLICY
MACHINE_PROCESSOR_POWER_POLICY
POWER_ACTION_POLICY
POWER_POLICY
POWERBROADCAST_SETTING
PROCESSOR_POWER_INFORMATION
PROCESSOR_POWER_POLICY
PROCESSOR_POWER_POLICY_INFO
SYSTEM_BATTERY_STATE
SYSTEM_POWER_CAPABILITIES
SYSTEM_POWER_INFORMATION
SYSTEM_POWER_LEVEL
SYSTEM_POWER_POLICY
SYSTEM_POWER_STATUS
USER_POWER_POLICY

각각의 내용을 보면, 중복되는것도 있고 포함관계에 있는것도 있고.. 여튼 이리저리 복잡한 듯 하다.
일단 이녀석들의 내용을 알아야 원하는 데이터를 가져오거나 바꿀 수 있을 듯 한데.. -_-;;
귀찮다.. ㅋ

대충 계층도랄까? 포함관계에 있는 녀석들을 보니 이렇더군..
GLOBAL_POWER_POLICY
           - GLOBAL_MACHINE_POWER_POLICY
                      - SYSTEM_POWER_STATUS
           - GLOBAL_USER_POWER_POLICY
                      - POWER_ACTION_POLICY
                                 - POWER_ACTION

POWER_POLICY
           - USER_POWER_POLICY       
                      - POWER_ACTION_POLICY
                                 - POWER_ACTION
           - MACHINE_POWER_POLICY   
                      -  SYSTEM_POWER_STATUS

MACHINE_PROCESSOR_POWER_POLICY   
           -  PROCESSOR_POWER_POLICY   
                      -  PROCESSOR_POWER_POLICY_INFO

SYSTEM_POWER_POLICY   
           -  POWER_ACTION_POLICY
                      - POWER_ACTION
           - SYSTEM_POWER_STATUS
           - SYSTEM_POWER_LEVEL   
                      - POWER_ACTION_POLICY
                                 - POWER_ACTION
                       - SYSTEM_POWER_STATUS

SYSTEM_POWER_CAPABILITIES   
           - BATTERY_REPORTING_SCALE
           - SYSTEM_POWER_STATUS

ADMINISTRATOR_POWER_POLICY   
           - SYSTEM_POWER_STATUS

PROCESSOR_POWER_INFORMATION

POWERBROADCAST_SETTING

SYSTEM_POWER_INFORMATION

SYSTEM_BATTERY_STATE

BATTERY_INFORMATION

BATTERY_MANUFACTURE_DATE

BATTERY_QUERY_INFORMATION  

BATTERY_REPORTING_SCALE

BATTERY_SET_INFORMATION

BATTERY_STATUS

BATTERY_WAIT_STATUS

DISPLAY_BRIGHTNESS

해놓고 보니깐.. 이런 작업을 왜했나 싶은것이.. 필요 없는 짓을 한걸까? ㅋㅋ