질문과 답변

SetWindowPos와 과제 질문드립니다. 날짜:2021-2-4 11:30:59 조회수:14504
작성자 : Stranger
포인트 : 22
가입일 : 2021-02-01 07:02:45
방문횟수 : 8
글 3개, 댓글 5개
소개 :
작성글 보기
쪽지 보내기
SetWindowPos는 클라이언트 좌표를 사용하는걸로 알고 있습니다.
그래서 
    case WM_LBUTTONDOWN:
        SetWindowPos(hBtn, NULL, LOWORD(lParam), HIWORD(lParam), 0, 0, SWP_NOSIZE | SWP_NOZORDER);
        return 0;
이와 같이 작성해도 마우스로 클릭한 위치로 윈도우의 좌표가 변경됩니다.
그런데, 윈도우를 부모윈도우의 중심으로 이동시키는 과제를 푸는 중에 이와 같은 함수를 작성했는데
void MoveToParentCenter(HWND hWnd)
{
    HWND hWndParent = GetParent(hWnd);
    WINDOWPLACEMENT WndPl;
    WndPl.length = sizeof(WINDOWPLACEMENT);
    GetWindowPlacement(hWndParent, &WndPl);
    if (WndPl.showCmd == SW_MINIMIZE) {
        ShowWindow(hWndMain, SW_SHOWNORMAL);
    }
    GetClientRect(hWndParent, &WndPl.rcNormalPosition);  //GetWindowPlacement 함수가 화면좌표를 줘서 다시 좌표 구함.
    RECT hrt; GetClientRect(hWnd, &hrt);
    
    hrt.left = WndPl.rcNormalPosition.right / 2 - hrt.right / 2;
    hrt.top = WndPl.rcNormalPosition.bottom / 2 - hrt.bottom / 2;
    SetWindowPos(hWnd, hWndParent, hrt.left, hrt.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
정상적으로 동작하지 않고 오히려 이동시킬 윈도우가 메인 윈도우의 화면 밖으로 나가는 경우가 발생했습니다.
결국 2가지 의문을 갖게 됐는데 답변해주셨으면 합니다.

1. GetWindowPlacement 함수를 사용하면 작업영역(Client) 좌표를 구할 수 있다고 했는데 왜 화면영역(Window) 좌표를 얻게 된건가요?

2.SetWindowPos는 작업영역 좌표를 사용한다고 배웠습니다. 그렇다면 이동시킬 윈도우와 작업영역 좌표만을 주는데 이 작업영역 좌표는 어느 윈도우를 기준으로 한 것입니까? 이동시킬 윈도우의 부모윈도우인가요?

이 두 가지 의문만 해결되면 과제를 원활하게 수행할 수 있을 것 같은데, 제가 더 알아야 하는게 있으면 알려주시면 감사하겠습니다.
참고로 제가 만든 코드에서 SetWindowPos 함수를 실행했을 때 매개변수로 준 x,y가 화면좌표처럼 쓰였습니다. 이것도 왜 그런지 모르겠습니다.

목록보기 삭제 수정 신고 스크랩

작가K 2월4일 11:21:10  

1번 답변은 앞 질문에서 말씀 드렸다시피 워크에리어 좌표입니다. 화면 좌표와 유사하다고 보시면 됩니다.
SetWindowPos가 사용하는 좌표는 윈도우 속성에 따라 다릅니다. 차일드라면 당연히 부모 윈도우의 작업영역 기준 좌표가 되겠지만 오버랩드 윈도우라면 그 부모가 데스크탑이므로 화면 좌표가 됩니다. 작성하신 코드에서 hWnd가 오버랩드, 즉 메인 윈도우이므로 이때 지정한 좌표는 화면 좌표로 해석될 거 같습니다.
레퍼런스에서 API 함수를 찾아 보시면 해당 좌표의 의미가 무엇인지, 어떤 경우에 어떤 좌표인지 대부분의 경우 설명이 되어 있으니 항상 레퍼런스를 참고하십시오. 과제가 무엇인지 구체적으로 알려 주시고 작성하신 코드와 원하는 코드를 보여 주시면 어떤 문제점이 있는지 여러 회원님들이 알 수 있을 거 같네요.

Stranger 2월5일 12:30:56  

1번에 대한 답변은 결론적으로 "SetWindowPos 함수는 첫 번째 인자로 준 윈도우(핸들)의 부모 윈도우를 기준으로 한 좌표를 사용한다."라고 해석해도 되겠나요? 이런 해석이라면 차일드 윈도우가 부모 윈도우인 메인 윈도우의 좌표를 사용하는 것이고, 메인 윈도우의 부모는 데스크탑이니 데스크탑의 좌표를 사용하는 것이니까요.
그리고 과제는 "대화상자가 부모 윈도우의 정중앙에 나타나게 하는 것"입니다. 그래서 위 함수에서 인자로 받은 hWnd는 대화상자의 핸들이였는데, 메인 윈도우가 대화상자를 만들어주니 대화상자의 속성이 차일드속성이라고 착각했었네요. 알고보니 메인윈도우 밖으로 나갈 수 있는 오버랩드 윈도우였는데말이죠.

답변해주셔서 조금은 알겠지만 아직도 좌표의 종류에 대해 조금은 헷갈리는데, 좌표의 종류는 화면영역(윈도우영역),작업영역(클라이언트영역),워크에리어(작업표시줄을 제외한 윈도우영역) 이 세 가지인가요? 워크에리어를 한글로 번역하면 작업영역같은데 이게 어떻게 된건지..


로그인하셔야 댓글을 달 수 있습니다.