2011-04-16 44 views
5

và ngày tốt lành cho tất cả các bạn. Đây là bài viết đầu tiên của tôi ở đây. Tôi đã đọc "Lập trình Windows với MFC - J Prosise (MS Press)"
Trong chương thứ hai tôi đi qua 2 chức năng GDI đó thực sự bối rối cho tôi, tôi trích dẫn nội dung:Lẫn lộn trong hai chức năng MFC GDI

Thật dễ dàng để có được SetViewportOrg và SetWindowOrg bối rối, nhưng sự khác biệt giữa chúng thực sự khá rõ ràng. Thay đổi nguồn gốc khung nhìn thành (x, y) bằng SetViewportOrg yêu cầu Windows ánh xạ điểm lôgic (0,0) đến điểm thiết bị (x, y). Thay đổi nguồn gốc của cửa sổ thành (x, y) với SetWindowOrg thực chất là ngược lại, yêu cầu Windows ánh xạ điểm lôgic (x, y) đến điểm thiết bị (0,0) - góc trên bên trái của bề mặt hiển thị. Trong chế độ ánh xạ MM_TEXT, sự khác biệt thực sự duy nhất giữa hai hàm là dấu hiệu của x và y. Trong các chế độ lập bản đồ khác, có nhiều điều hơn thế bởi vì các giao dịch SetViewportOrg trong tọa độ thiết bị và giao dịch SetWindowOrg trong các tọa độ logic

Tôi thực sự bối rối với điều này, cũng giống như chúng ta thay đổi nguồn gốc điểm quan sát (50,50) và sau đó sử dụng dc.ellipse (0,0,50,50) nó sẽ bắt đầu từ điểm thiết bị (50,50) như là nguồn gốc, nhưng nếu chúng ta thay đổi nguồn gốc cửa sổ thành (50,50) thì điều đó có nghĩa là điểm logic (50 , 50) sẽ được ánh xạ tới (0,0) nếu vậy, không phải hình elip sẽ nằm ngoài khu vực của khách hàng ở khu vực phía trên không? Và chế độ lập bản đồ là gì MM_LOWENGLISH hoặc cái gì khác? Tình hình sẽ thay đổi như thế nào? Xin vui lòng nếu ai đó có thể làm sáng tỏ vấn đề này, tôi sẽ rất biết ơn

Trả lời

6

Đây là một câu hỏi khá phức tạp, chủ yếu là vì bạn có hai tập tọa độ hoàn toàn riêng biệt để xử lý và (chỉ để giữ mọi thứ thú vị) Windows sử dụng gần như ngược lại của các thuật ngữ phần còn lại của thế giới sử dụng.

Câu trả lời ngắn gọn chỉ là không sử dụng SetWindowOrg. Tôi khá chắc chắn tôi chưa bao giờ sử dụng tốt nó trong mã thực.

SetViewportOrg hữu ích và nó thực sự đơn giản hơn mô tả làm cho âm thanh phát ra - bạn chỉ cần chọn nơi bạn muốn xuất xứ. Ví dụ: bạn có thể muốn bản vẽ của mình bắt đầu từ góc dưới cùng bên trái của cửa sổ. Bạn muốn làm điều đó với một cái gì đó như:

CRect rect; 
GetClientRect(&rect); 

pDC->SetViewportOrg(0, rect.Height()); 

OTOH, nếu bạn muốn để có thể vẽ cả số âm và dương tính, bạn có thể muốn x = 0 là ở phía bên trái của cửa sổ, nhưng y = 0 được đặt giữa nửa đầu và cuối cửa sổ. Bạn muốn làm một cái gì đó như:

// get rect as above. 
pDC->SetViewportOrg(0, rect.Height()/2); 

Nếu bạn muốn là trung tâm của cửa sổ để được bạn (0,0), bạn muốn sử dụng:

// again, get rect like above 
pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2); 

Lưu ý rằng chính việc sử dụng một trong hai chế độ này là với chế độ ánh xạ được đặt thành MM_ISOTROPIC hoặc MM_ANISOTROPIC - đây là nơi bạn có thể đặt hoàn toàn tọa độ của riêng mình. Với các chế độ khác [MM_TEXT hoặc MM_ (LO | HI) (TIẾNG ANH | METRIC)], nó tự động thiết lập nguồn gốc cho bạn.

+0

Cảm ơn sự giúp đỡ. Lúc đầu, tôi cũng nghĩ rằng phải gắn bó với nguyên tắc của KISS nhưng đọc nó nhiều lần để nắm bắt nó hoàn toàn chỉ làm tôi bối rối. – Razort4x