윈도우 메모장에서 현재 캐럿으로부터 블럭을 설정한 후 클립보드로 복사할 수 있게 캐럿위치를 구하는 함수를 알고 싶습니다.
GetSel()은 현재 에디터 내에서 캐럿의 위치(열과 행 또는 인덱스)를 구하는 함수로 에디터에 선택된 부분이 없더라도 이 함수를 쓸 수 있습니다. 이 경우는 선택 부분의 시작 위치와 끝위치가 같으므로 블럭을 설정하면 현재 캐럿의 위치를 인덱스로 삼아 라인 위치로 바꿔 줍니다. 이 경우 사용하는 함수가 LineFromChar()입니다. 그리고 몇 번째 컬럼에 있는가는 캐럿위치에서 LineIndex() 로 얻은 값을 빼는 식으로 두 함수를 조합하면 알아낼 수 있습니다.
화면에 그려진 사각형을 특정 버튼을 눌러 프린트로 출력하고 싶습니다.
사각형을 출력하는 정도라면 애플리케이션 위저드가 생성해 주는 프린트 소스로 충분합니다. 처음 애플리케이션을 만들 때 프린트 기능을 추가하면 CView에 onPrint 함수가 생깁니다. 이 함수는 DC를 onDraw() 로 넘겨주는데, 여기서 onDraw() 는 주어진 DC를 화면이라 생각하고 그리게 됩니다. 그리고 버튼을 누르면 발생하는 버튼 클릭 이벤트에 SendMessage(WM_COMMAND, ID_FILE_PRINT); 또는 SendMessage(WM_COMMAND, ID_FILE_PRINT_PREVIEW);를 덧붙이면 파일에서 프린트로 보낼 수 있습니다.
참고로 여러 페이지의 도큐먼트라든가 혹은 큰 화면을 여러 장으로 나눠 찍는 복잡한 프린트를 원한다면 onPrint() 의 도움말을 참조하기 바랍니다.
비주얼 C++/MFC 4.0 으로 작성한 프로그램을 제가 짠 프로그램에서 실행하고, 필요에 따라서는 제어하고 싶습니다. 말하자면 IPC(InterProcess Communication)가 되도록 하는 거죠. 마치 윈도우 매니저가 특정 프로그램을 죽일 수 있는 것처럼 제 프로그램에서 다른 프로그램을 손쉽게 제어하고 싶습니다.
CreateProcess 도움말을 보면 알겠지만 세부 사항을 조목조목 지정해 프로세스를 시작할 수 있으므로 다른 애플리케이션을 제어하는데 문제가 없을 것입니다. 물론 제어할 필요가 없는 항목은 디폴트로 주면 됩니다.
참고로 이 함수의 10번째 인수인 lpProcessInformation에는 이 프로세스의 시작 정보가 들어있는데, 여기에 시작 프로세스 핸들과 메인 쓰레드 핸들이 담겨져 리턴됩니다. 참고로 다음 SuspendThread()와 ResumeThread()를 사용하면 메인 쓰레드를 잠깐 멈출 수도 있고, TerminateThread()로 프로세스의 모든 쓰레드를 종료하는 등 다른 애플리케이션을 쉽게 제어할 수 있습니다.
폼뷰에 있는 라디오 버튼을 선택할 경우 화면의 다른 컨트롤 중 일부를 완전히 그레이(gray)로 처리하고 싶습니다. 즉 에디트 컨트롤 입력이나 라디오 버튼을 체크하지 못하게 하는 식으로 컨트롤에 접근할 수 없도록 하고자 합니다.
어떤 라디오 버튼을 선택했을 경우에 특정 컨트롤을 쓸 수 없게 만드는 일은 생각보다 쉽습니다. DDX(Dialog Data eXchange) 메카니즘을 이용해서 컨트롤과 맵핑되는 변수를 이용하거나 혹은 GetDlgItem()를 사용해 컨트롤의 포인터를 얻은 후 멤버 함수 EnableWindow(BOOL)로 해결하면 됩니다.
윈도우 95의 '찾기'처럼 폼뷰를 만들었는데 윈도우 크기를 변경할 경우 함께 내부의 컨트롤 크기도 변하게 하고 싶습니다.
만약 윈도우 95에서만 쓴다면 WM_SIZE 에서 처리해주면 되지만, 플러스팩을 설치했다거나 윈도우 NT 4.0에서 사용하는 경우는 곤란합니다. 왜냐 하면 윈도우 크기를 조절할 때 윈도우는 동적으로 계속 그려지므로 WM_SIZE에서 처리해 주면 크기조절이 끝나고 나서야 컨트롤을 다시 그리므로 좋은 방법이라 할 수 없죠. 그러므로 컨트롤을 다시 그려주는 부분이 필요합니다.
한 번은 꼭 호출되는 onInitDialog()에서 바로 처리하는 것보다 따로 분리해서 작성한 후 호출하는 것이 좋습니다. 우선 필요한 컨트롤은 모두 DDX를 이용해 컨트롤 변수로 만들어 줍니다 (API에서는 GetDlgItem()등의 함수 이용).
void ResizeControlToParent(void) {
CRect rect;
GetClientRect(&rect);
m_List1.MoveWindow(rect.left+10, rect.top+10,
(rect.right-rect.left)/2, (rect.bottom-rect.top)/3, TRUE);
m_Edit1.MoveWindow(...........................)
...
return;
}
이렇게 만든 함수를 onInitDialog()와 onSize() 또는 onSizing()에서 불러 주면 되는 거죠.
참고로 윈도우가 최소화될 경우만 유념하면 됩니다. 가령 윈도우 크기를 얻어서 컨트롤을 그릴 때 'rect.right-50' 식으로 '50'을 정수 처리하면 최소화될 때 값이 음수값이 되므로 'Assertion Failure' 또는 '이 프로그램이 잘못된 연산을 수행하여...'라는 메시지를 만나게 됩니다.
비주얼 C++로 프로그래밍을 하던 중 응용 프로그램이 실행된 경로를 알아야 할 필요가 생겼습니다.
프레임웍은 응용 프로그램의 초기화 과정에서 GetModuleFilesName을 호출하고 도움말 파일에 대한 경로를 CWinApp::m_pszHelpFilePath에 저장합니다.
응용 프로그램이 실행된 디렉토리를 찾기 위해 이 데이터 멤버를 사용하는 방법은 다음과 같습니다. 여기서 _splitpath가 실행루틴이며, _MAX_DIR과 _MAX_DRIVE는 헤더파일인 STDLIB.H에 정의돼 있습니다.
void GetLaunchDir(CString& strLaunched)
{
TCHAR szDir[_MAX_DIR];
TCHAR szDrive[_MAX_DRIVE];
_splitpath(AfxGetApp()->m_pszHelpFilePath,
szDrive, szDir, NULL, NULL);
strLaunched.Format(_T("%s%s"), szDrive, szDir);
}
- The end of this article -
ARTICLE다른 프로젝트에 있는 리소스를 현재 프로젝트에 복사하고 싶습니다.
리소스를 드래그 앤 드롭이나 임포트로 넣을 수 있는지요.
물론 가능합니다. 다른 프로젝트로부터 리소스르 사용하는 방법에는 리소스를 임포트(Import)하는 방법과 다른 프로젝트의 리소스 스크립트 파일(.rc)에서 직접 리소스를 복사해 오는 두 가지 방법이 있습니다.
리소스를 임포트하려면 임포트 메뉴에서 'Insert->Resource' 를 선택한 후 'Insert Resource'란 다이얼로그가 나오면 리소스 타입중에 하나를 더블클릭합니다. 그러면 새로운 리소스가 추가됩니다. 기존 프로젝트에서 비트맵(*.bmp, *.dib) 파일, 아이콘 파일(*.ico), 커서 파일(*.cur), 웨이브 파일(*.wav), 비주얼 베이직 폼 형태의 리소스를 복사하려면 'Import' 버튼을 누르면 간단히 추가할 수 있습니다.
다른 프로젝트의 리소스 스크립트로부터 직접 복사하는 과정은 아주 간단합니다. 우선 'File->Open'을 선택하고, 원본이 되는 리소스 스크립트 파일(*.rc) 을 연후 윈도우 탐색기에서 복사하듯이 드래그 앤 드롭으로 프로젝트 창(Project Workspace)에 옮겨 주면 됩니다. 단 <Ctrl>키를 누르지 않고 옮기면, 이전 프로젝트의 리소스가 사라지는 것에 유의해야 합니다. Resource.h 파일의 ID관리는 디벨롭퍼 스튜디오가 내부적으로 해결해 주므로 신경쓰지 않아도 됩니다.
바탕화면에 그림을 그리려 합니다. 그리고 일반 윈도우에 그리는 것과의 차이점도 알고 싶습니다.
우선 바탕화면도 하나의 윈도우이므로 바탕화면의 윈도우 핸들을 알아야 합니다. 즉 일반윈도우에 그리는 것과 전혀 다를게 없습니다 .바탕 호면에 직접 그림을 그리게 되면 화면에 떠 있는 모든 윈도우에 겹쳐져서 그려지므로 바탕 화면또는 일반 윈도우에만 그리고 싶다면 별도의 작업이 필요합니다.
여기에서는 화면 왼쪽 위부터 빗금이 그어지는 예로 필요한 부분만 보이기 위해 윈도우를 만들지 않았습니다.
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpszArgs, int nWinMode)
{
HWND hwnd = GetDesktopWindow();
// 바탕화면의 윈도우 핸들 얻기
HDC hdc = GetWindowDC(hwnd);
// 바탕화면의 DC 핸들 얻기
// GetWindowDC를 쓴다.
HPEN hPen;
register int i;
for(i=0; i<=255; i++) {
hPen = CreatePen(PS_SOLID, 0, RGB(i, i, i));
// 원하는 색으로 펜 만들기
HGDIOBJ hOldPen = SelectObject(hdc, hPen);
// 펜을 현재 DC에서 선택
// 펜 핸들 보관
MoveToEx(hdc, i*3, 0, NULL);
LineTo(hdc, 0, i*3);
// 선택된 펜으로 선을 긋는다.
SelectObject(hdc, hOldPen);
// 원래대로 펜 돌려놓기
DeleteObject(hPen);
// 필요없는 펜 제거
}
ReleaseDC(hwnd, hdc);
// DC를 반납하고 그리기 작업을 마친다.
}
[↓Click! 캐럿의 위치를 알려면 / onPrint()로 프린트 기능을 / 다른 애플리케이션 제어 방법
컨트롤을 사용할 수 없게 처리하려면 / 컨트롤 크기를 뷰에 맞추기 /
응용 프로그램이 실행된 디렉토리를 찾으려면]
'IT_Programming > MFC · API' 카테고리의 다른 글
툴바 숨기기/보이기 옵션 주기 / 클라이언트 영역을 클릭해 윈도우를 이동 (0) | 2007.12.25 |
---|---|
윈도우 3.1의 다이얼로그 구현 / 프레임 메뉴를 동적으로 변환 (0) | 2007.12.25 |
CListCtrl에 컬럼 넣기 / 다이얼로그에서 뷰 포인터 액세스 (0) | 2007.12.25 |
응용 프로그램을 최소 크기 만들기 / 에디트 박스에서 엔터키 확인 방법 (0) | 2007.12.25 |
CoCreateInstance 함수 (0) | 2007.12.13 |