2015-08-03 22 views
18

Tôi đang làm cho ứng dụng của tôi nhận thức dpi trên mỗi màn hình bằng cách đặt <dpiAware>True/PM</dpiAware> trong tệp kê khai. Tôi có thể xác minh với quá trình thám hiểm rằng điều này thực sự là làm việc hoặc bằng cách gọi GetProcessDpiAwareness.Làm thế nào để bạn mở rộng thanh tiêu đề trên ứng dụng giành chiến thắng DPI?

Đây là tất cả hoạt động tốt và tôi có thể mở rộng bất cứ điều gì trong khu vực khách hàng tốt trong mã của tôi. Tuy nhiên, vấn đề duy nhất của tôi là nếu tôi kéo ứng dụng của mình từ màn hình hệ thống dpi sang màn hình không phải hệ thống dpi, thanh tiêu đề và bất kỳ menu hệ thống nào sẽ trở nên quá lớn hoặc quá nhỏ. Đây không phải là trường hợp đối với hầu hết các ứng dụng tích hợp (ví dụ: calc, trình duyệt cạnh, v.v.) do đó phải có để mở rộng ứng dụng đúng cách. Có ai làm thế nào các devs tại MS đã làm điều này?

Ảnh chụp màn hình bên dưới sẽ giải thích vấn đề của tôi tốt hơn. Cũng lưu ý, rằng phần đệm giữa nút đóng, tối và tối đa là khác nhau khi nó được thu nhỏ (96dpi).

Screenshot

Sample app Tôi gắn một ứng dụng rất đơn giản đó là mỗi màn dpi biết.

+1

Mã trên mỗi màn hình của bạn trông như thế nào? Trình xử lý cho WM_DPICHANGED? –

+0

Ứng dụng của bạn có phải là ứng dụng toàn cầu không? Cả hai máy tính và Edge là – melak47

+0

@ melak47 Nó không phải là một ứng dụng toàn cầu. Đây là một ứng dụng cũ - chỉ muốn làm cho nó quy mô đúng trên tất cả các màn hình của tôi. Bạn có nghĩ rằng các cửa sổ sẽ mở rộng thanh tiêu đề nếu nó là một ứng dụng toàn cầu? – Dealdiane

Trả lời

7

Có ai biết các nhà phát triển tại MS đã làm điều này không?

Điều này có một câu trả lời khá đáng thất vọng. Sử dụng WinCheat của Alin Constantin và kiểm tra cửa sổ cấp cao nhất của Máy tính, tôi thấy kích thước cửa sổ 320x576 và kích thước máy khách cũng là 320x576.

Nói cách khác, Microsoft hoàn toàn tránh được vấn đề bằng cách loại bỏ khu vực không phải khách hàng của cửa sổ, thay vào đó hãy đặt mọi thứ vào khu vực ứng dụng khách. Làm cho công việc này tốt cho bạn có thể liên quan đến bản vẽ tùy chỉnh của thanh tiêu đề.

Điều đáng chú ý là Máy tính và ví dụ: Windows Explorer không sử dụng cùng màu cho thanh tiêu đề. Máy tính làm bản vẽ tùy chỉnh của thanh tiêu đề sẽ giải thích rằng hoàn hảo.

+0

Cảm ơn. Đó là chính xác những gì tôi đã lo lắng về mặc dù. Tôi thực sự không hiểu lý do đằng sau điều này. Nếu họ cố định điều này theo cách thích hợp trong win10, mọi người sẽ được hưởng lợi từ nó. – Dealdiane

+0

Tôi đã nghiên cứu thêm về điều này và có vẻ như các ứng dụng UWP sẽ không gặp vấn đề này. Điều này là do lớp [ApplicationViewTitleBar] mới (https://msdn.microsoft.com/library/windows/apps/windows.ui.viewmanagement.applicationviewtitlebar.aspx) trong Windows 10. Giống như @hvd cho biết, trong một ứng dụng UWP không có khu vực không phải khách hàng. Thanh gạch được vẽ trong vùng máy khách nhưng vẫn hoạt động như nó không cần mã hóa thêm. Tôi muốn chúng ta có thể có được hành vi tương tự ra khỏi hộp hoặc ít nhất gọi một số apis để đạt được điều tương tự trong một ứng dụng _native_ mặc dù. – Dealdiane

+0

Tôi không nghĩ rằng điều này giải thích hoàn toàn. Ví dụ cmd.exe hoặc hộp thoại Win-R có kích thước khác nhau cho cửa sổ và kích thước khách hàng nhưng MAGICALLY vẽ lại cửa sổ chrome, menu cửa sổ, v.v. – Jabe

0

Các documentation nói:

Lưu ý rằng khu vực phi-client của một mỗi màn hình-DPI ứng dụng biết được không thu nhỏ lại bởi Windows, và sẽ xuất hiện tương ứng nhỏ hơn trên một màn hình DPI cao.

Các ứng dụng Microsoft mà bạn liên kết để giải quyết vấn đề này bằng cách xóa khu vực không phải khách và làm cho khu vực khách hàng bao phủ toàn bộ cửa sổ.

0

Điều tra khác về chủ đề này.

Thiết lập hệ thống: hai màn hình, một màn hình là 96 dpi, một màn hình khác là 267 dpi (Microsoft Surface 4).

cửa sổ kiểm tra được chuyển đến trung học 96 màn dpi:

Dưới đây là render (sai, IMO) với <dpiAware>true/pm</dpiAware> trong manifest:

enter image description here

Lưu ý kích thước khổng lồ của thanh chú thích và kích cỡ sai biểu tượng cửa sổ.

Và đây là đúng render sử dụng <dpiAware>true</dpiAware>

enter image description here

Và tôi nghi ngờ rằng tài liệu MSDN được rõ ràng gây hiểu lầm về giá trị của PROCESS_DPI_AWARENESS. Tôi không thấy bất kỳ sự khác biệt nào về thông báo và kiểu giữa <dpiAware>true</dpiAware><dpiAware>true/pm</dpiAware>. Cái sau chỉ làm cho chú thích lớn hơn. Trong cả hai trường hợp, ứng dụng nhận được tin nhắn WM_DPICHANGED trong khi di chuyển giữa các màn hình với DPI khác nhau.

Sigh.

+0

Như đã đề cập, trong Bản cập nhật Kỷ niệm (và các phiên bản mới hơn của Windows 10), bạn có thể nhận được vùng không phải khách hàng đến phạm vi DPI bằng cách gọi EnableNonClientDpiScaling từ WM_NCCREATE. Kiểm tra mẫu này: https://github.com/Microsoft/Windows-classic-samples/tree/master/Samples/DPIAwarenessPerWindow – peterfelts

+0

Trong bản cập nhật Windows 10 người sáng tạo sẽ có ngữ cảnh nhận thức DPI mới DPI_AWARENESS_PER_MONITOR_AWARE_V2 cho phép không phải khách hàng mở rộng theo mặc định cho cửa sổ cấp cao nhất. – peterfelts

10

Bản cập nhật kỷ niệm Windows 10 (v1607) đã thêm API mới mà bạn phải gọi để kích hoạt quy mô DPI của các khu vực không phải khách hàng: EnableNonClientDpiScaling. Chức năng này nên được gọi khi nhận được WM_NCCREATE. Tin nhắn được gửi đến thủ tục gọi lại của cửa sổ trong khi tạo cửa sổ.

Ví dụ:

case WM_NCCREATE: 
{ 
    if (!EnableNonClientDpiScaling(hWnd)) 
    { 
     // Error handling 
     return FALSE; 
    } 

    return DefWindowProcW(...); 
} 

Nếu bối cảnh DPI nhận thức của ứng dụng là DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, sau đó gọi EnableNonClientDpiScaling nên được bỏ qua, vì nó sẽ không có hiệu lực, mặc dù chức năng vẫn sẽ trở lại thành công.

Từ the documentation:

Non-client mở rộng quy mô cho các cửa sổ cấp cao nhất không được kích hoạt theo mặc định. Bạn phải gọi API này để kích hoạt nó cho từng cửa sổ cấp cao nhất mà bạn muốn tự động mở rộng vùng không phải khách hàng. Một khi bạn làm, không có cách nào để vô hiệu hóa nó. Việc kích hoạt quy mô không phải khách hàng có nghĩa là tất cả các khu vực được vẽ bởi hệ thống cho cửa sổ sẽ tự động mở rộng để đáp ứng với những thay đổi của DPI trên cửa sổ. Điều đó bao gồm các khu vực như thanh phụ đề, thanh cuộn và thanh trình đơn. Bạn muốn gọi EnableNonClientDpiScaling khi bạn muốn hệ điều hành chịu trách nhiệm tự động hiển thị các khu vực này ở kích thước chính xác dựa trên API của màn hình.

Xem this blog post để biết thêm thông tin về các thay đổi tỷ lệ DPI trong Windows 10 AU.

Các vấn đề liên quan