Уж прошу простить модераторов за поднятие старой темы, но так же столкнулся с её проявлением, и поиском нашёл решения.
Это проблема .NET2.0-3.5SP1
VisibleClipBounds returns always same valueVisibleClipBounds does not produce correct results for different PageUnitSetting the value of Graphics.PageUnit under .NET 2.0В .NET1.1 (и наверное в .NET1.0 тоже) и в текущей (2й) бете .NET4.0 всё нормально
%SYSTEMROOT%\Microsoft.NET\Framework\v1.1.4322\vbc WhatSize.vb PrintableForm.vb /main:WhatSize /r:System.dll,System.Drawing.dll,System.Windows.Forms.dll
%SystemRoot%\Microsoft.NET\Framework\v4.0.21006\vbc WhatSize.vb PrintableForm.vb /main:WhatSize /r:System.dll,System.Drawing.dll,System.Windows.Forms.dll
Только при выводе на принтер какие-то сложности.
P.S.
Под Win 7 RC (7100) где и установлена вторая бета .NET 4.0 проблем нету и в .NET2.0-3.5SP1, интересно почему. (С печатью все равно проблема таже).
P.S.S.
Не пробовал, поможет ли в VB.NET если обойти .NET GDI врапер и работать с
Graphics::GetVisibleClipBounds Method напрямую, аналогично тому как в VB6 напрямую используют GDI+.
P.S.S.S
В следующей программе
WhatSizeTransform.vb, далее по книге Чарльза, не используется VisibleClipBounds, по сему данная ошибка там не проявляется.
И тем не менее, хотелось увидеть, как обходить GdiPlus .NET врапер.
Первое что я сделал, это убедился что это действительно не проблема GdiPlus, для этого набрал код в Visual C++.
- Код: Выделить всё
//cl WhatSize_GdiPlus.cpp /D "UNICODE" /D "_UNICODE" Kernel32.lib User32.lib GdiPlus.lib /link /subsystem:windows /MERGE:.rdata=.text /SECTION:.text,EWR
#include <windows.h>
#include <stdio.h>
#include <GdiPlus.h>
using namespace Gdiplus;
#pragma comment(lib, "GdiPlus.lib")
void DoIt(HDC *, Brush *, int *, Unit);
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
int WINAPI wWinMain (HINSTANCE hThisInst, HINSTANCE hPrevInst, wchar_t *lpszArgs, int nWinMode)
{
WNDCLASS wcl = {0}; //wcl.cbClsExtra = 0; wcl.cbWndExtra = 0; wcl.lpszMenuName = NULL;
wcl.style = CS_HREDRAW | CS_VREDRAW;
wcl.lpfnWndProc = WindowFunc;
wcl.hInstance = hThisInst;
wcl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
wcl.hbrBackground = (HBRUSH)COLOR_WINDOW;
wcl.lpszClassName = L"ClassName";
if(!RegisterClass (&wcl))
return -1;
HWND hWndMainWindow = CreateWindow (
L"ClassName", L"What size?",
WS_OVERLAPPEDWINDOW,//WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT,
300, 300,
HWND_DESKTOP,
NULL,
hThisInst,
NULL);
if (!hWndMainWindow)
return -1;
ULONG_PTR gdiplusToken = 0;
GdiplusStartupInput gdiplusStartupInput = 0;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
ShowWindow (hWndMainWindow, nWinMode);
UpdateWindow (hWndMainWindow);
MSG msg = {0};
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
GdiplusShutdown(gdiplusToken);
return (int)msg.wParam;
}
LRESULT CALLBACK WindowFunc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
Brush *br = new SolidBrush(Color::Black);
int y = 0;
PAINTSTRUCT ps = {0};
HDC hDc = BeginPaint(hWnd, &ps);
DoIt(&hDc, br, &y, Unit::UnitPixel);
DoIt(&hDc, br, &y, Unit::UnitDisplay);
DoIt(&hDc, br, &y, Unit::UnitDocument);
DoIt(&hDc, br, &y, Unit::UnitInch);
DoIt(&hDc, br, &y, Unit::UnitMillimeter);
DoIt(&hDc, br, &y, Unit::UnitPoint);
EndPaint(hWnd, &ps);
}
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
void DoIt(HDC *hDc, Brush *br, int *y, Unit gu)
{
Graphics grfx(*hDc);
GraphicsState gs = grfx.Save();
grfx.SetPageUnit (gu);
grfx.SetPageScale (1);
Rect rect;
grfx.GetVisibleClipBounds(&rect);
Size sz;
rect.GetSize(&sz);
wchar_t Buff[MAX_PATH] = L"";
swprintf(Buff, MAX_PATH, L"{Width = %i ; Height = %i}", sz.Width, sz.Height);
switch(gu)
{
case (Unit::UnitWorld):
lstrcat(Buff, L" UnitWorld");
break;
case (Unit::UnitDisplay):
lstrcat(Buff, L" UnitDisplay");
break;
case (Unit::UnitPixel):
lstrcat(Buff, L" UnitPixel");
break;
case (Unit::UnitPoint):
lstrcat(Buff, L" UnitPoint");
break;
case (Unit::UnitInch):
lstrcat(Buff, L" UnitInch");
break;
case (Unit::UnitDocument):
lstrcat(Buff, L" UnitDocument");
break;
case (Unit::UnitMillimeter):
lstrcat(Buff, L" UnitMillimeter");
break;
default:
lstrcat(Buff, L" UnitUNKNOWN");
break;
}
grfx.Restore (gs);
Font MyFont(L"Arial", 10);
grfx.DrawString (Buff, -1, &MyFont, PointF(0, *y), br);
*y += 15;
}
Как видно на скрине,
это действительно не проблема GdiPlus.
Попытка пойти по пути наименьшего сопротивления не увенчалась успехом.
- Код: Выделить всё
Private Structure RECTF
Public Left As Single
Public Top As Single
Public Width As Single
Public Height As Single
End Structure
Private Enum GpStatus
Ok = &H0
GenericError = &H1
InvalidParameter = &H2
OutOfMemory = &H3
ObjectBusy = &H4
InsufficientBuffer = &H5
NotImplemented = &H6
Win32Error = &H7
WrongState = &H8
Aborted = &H9
FileNotFound = &HA
ValueOverflow = &HB
AccessDenied = &HC
UnknownImageFormat = &HD
FontFamilyNotFound = &HE
FontStyleNotFound = &HF
NotTrueTypeFont = &H10
UnsupportedlusVersion = &H11
lusNotInitialized = &H12
PropertyNotFound = &H13
PropertyNotSupported = &H14
End Enum
Private Declare Function GdipGetVisibleClipBounds Lib "GdiPlus.dll" (ByRef mGraphics As Graphics, ByRef mRect As RECTF) As GpStatus
'...
Private Sub DoIt(ByVal grfx As Graphics, ByVal br As Brush, _
ByRef y As Integer, ByVal gu As GraphicsUnit)
Dim gs As GraphicsState = grfx.Save()
grfx.PageUnit = gu
grfx.PageScale = 1
'Dim szf As SizeF = grfx.VisibleClipBounds.Size
Dim RF As RECTF
Dim Gp As GpStatus = GdipGetVisibleClipBounds(grfx, RF)
'Dim szf As SizeF = RF.Size
grfx.Restore(gs)
' grfx.DrawString(gu.ToString() & ":" & szf.ToString(), _
' Font, br, 0, y)
grfx.DrawString(gu.ToString() & ":" & RF.Width - RF.Left & " " & RF.Height - RF.Top, _
Font, br, 0, y)
y += CInt(Math.Ceiling(Font.GetHeight(grfx)))
End Sub
Программа выдаёт нули. Возможно нужно добавить явный старт GdiPlus, как в C++ варианте.
P.S.S.S.S
А вот VB6 вариант выдаёт одинаковые значение.
- Код: Выделить всё
Private Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type
Private Enum GpStatus
OK = &H0
GenericError = &H1
InvalidParameter = &H2
OutOfMemory = &H3
ObjectBusy = &H4
InsufficientBuffer = &H5
NotImplemented = &H6
Win32Error = &H7
WrongState = &H8
Aborted = &H9
FileNotFound = &HA
ValueOverflow = &HB
AccessDenied = &HC
UnknownImageFormat = &HD
FontFamilyNotFound = &HE
FontStyleNotFound = &HF
NotTrueTypeFont = &H10
UnsupportedlusVersion = &H11
lusNotInitialized = &H12
PropertyNotFound = &H13
PropertyNotSupported = &H14
End Enum
Private Enum GpUnit
UnitWorld = &H0
UnitDisplay = &H1
UnitPixel = &H2
UnitPoint = &H3
UnitInch = &H4
UnitDocument = &H5
UnitMillimeter = &H6
End Enum
Private Type RECTF
Left As Single
Top As Single
Width As Single
Height As Single
End Type
Private Enum Colors
AliceBlue = &HFFF0F8FF
AntiqueWhite = &HFFFAEBD7
Aqua = &HFF00FFFF
Aquamarine = &HFF7FFFD4
Azure = &HFFF0FFFF
Beige = &HFFF5F5DC
Bisque = &HFFFFE4C4
Black = &HFF000000
BlanchedAlmond = &HFFFFEBCD
Blue = &HFF0000FF
BlueViolet = &HFF8A2BE2
Brown = &HFFA52A2A
BurlyWood = &HFFDEB887
CadetBlue = &HFF5F9EA0
Chartreuse = &HFF7FFF00
Chocolate = &HFFD2691E
Coral = &HFFFF7F50
CornflowerBlue = &HFF6495ED
Cornsilk = &HFFFFF8DC
Crimson = &HFFDC143C
Cyan = &HFF00FFFF
DarkBlue = &HFF00008B
DarkCyan = &HFF008B8B
DarkGoldenrod = &HFFB8860B
DarkGray = &HFFA9A9A9
DarkGreen = &HFF006400
DarkKhaki = &HFFBDB76B
DarkMagenta = &HFF8B008B
DarkOliveGreen = &HFF556B2F
DarkOrange = &HFFFF8C00
DarkOrchid = &HFF9932CC
DarkRed = &HFF8B0000
DarkSalmon = &HFFE9967A
DarkSeaGreen = &HFF8FBC8B
DarkSlateBlue = &HFF483D8B
DarkSlateGray = &HFF2F4F4F
DarkTurquoise = &HFF00CED1
DarkViolet = &HFF9400D3
DeepPink = &HFFFF1493
DeepSkyBlue = &HFF00BFFF
DimGray = &HFF696969
DodgerBlue = &HFF1E90FF
Firebrick = &HFFB22222
FloralWhite = &HFFFFFAF0
ForestGreen = &HFF228B22
Fuchsia = &HFFFF00FF
Gainsboro = &HFFDCDCDC
GhostWhite = &HFFF8F8FF
Gold = &HFFFFD700
Goldenrod = &HFFDAA520
Gray = &HFF808080
Green = &HFF008000
GreenYellow = &HFFADFF2F
Honeydew = &HFFF0FFF0
HotPink = &HFFFF69B4
IndianRed = &HFFCD5C5C
Indigo = &HFF4B0082
Ivory = &HFFFFFFF0
Khaki = &HFFF0E68C
Lavender = &HFFE6E6FA
LavenderBlush = &HFFFFF0F5
LawnGreen = &HFF7CFC00
LemonChiffon = &HFFFFFACD
LightBlue = &HFFADD8E6
LightCoral = &HFFF08080
LightCyan = &HFFE0FFFF
LightGoldenrodYellow = &HFFFAFAD2
LightGray = &HFFD3D3D3
LightGreen = &HFF90EE90
LightPink = &HFFFFB6C1
LightSalmon = &HFFFFA07A
LightSeaGreen = &HFF20B2AA
LightSkyBlue = &HFF87CEFA
LightSlateGray = &HFF778899
LightSteelBlue = &HFFB0C4DE
LightYellow = &HFFFFFFE0
Lime = &HFF00FF00
LimeGreen = &HFF32CD32
Linen = &HFFFAF0E6
Magenta = &HFFFF00FF
Maroon = &HFF800000
MediumAquamarine = &HFF66CDAA
MediumBlue = &HFF0000CD
MediumOrchid = &HFFBA55D3
MediumPurple = &HFF9370DB
MediumSeaGreen = &HFF3CB371
MediumSlateBlue = &HFF7B68EE
MediumSpringGreen = &HFF00FA9A
MediumTurquoise = &HFF48D1CC
MediumVioletRed = &HFFC71585
MidnightBlue = &HFF191970
MintCream = &HFFF5FFFA
MistyRose = &HFFFFE4E1
Moccasin = &HFFFFE4B5
NavajoWhite = &HFFFFDEAD
Navy = &HFF000080
OldLace = &HFFFDF5E6
Olive = &HFF808000
OliveDrab = &HFF6B8E23
Orange = &HFFFFA500
OrangeRed = &HFFFF4500
Orchid = &HFFDA70D6
PaleGoldenrod = &HFFEEE8AA
PaleGreen = &HFF98FB98
PaleTurquoise = &HFFAFEEEE
PaleVioletRed = &HFFDB7093
PapayaWhip = &HFFFFEFD5
PeachPuff = &HFFFFDAB9
Peru = &HFFCD853F
Pink = &HFFFFC0CB
Plum = &HFFDDA0DD
PowderBlue = &HFFB0E0E6
Purple = &HFF800080
Red = &HFFFF0000
RosyBrown = &HFFBC8F8F
RoyalBlue = &HFF4169E1
SaddleBrown = &HFF8B4513
Salmon = &HFFFA8072
SandyBrown = &HFFF4A460
SeaGreen = &HFF2E8B57
SeaShell = &HFFFFF5EE
Sienna = &HFFA0522D
Silver = &HFFC0C0C0
SkyBlue = &HFF87CEEB
SlateBlue = &HFF6A5ACD
SlateGray = &HFF708090
Snow = &HFFFFFAFA
SpringGreen = &HFF00FF7F
SteelBlue = &HFF4682B4
Tan = &HFFD2B48C
Teal = &HFF008080
Thistle = &HFFD8BFD8
Tomato = &HFFFF6347
Transparent = &HFFFFFF
Turquoise = &HFF40E0D0
Violet = &HFFEE82EE
Wheat = &HFFF5DEB3
White = &HFFFFFFFF
WhiteSmoke = &HFFF5F5F5
Yellow = &HFFFFFF00
YellowGreen = &HFF9ACD32
End Enum
Private Enum FontStyle
FontStyleRegular = &H0
FontStyleBold = &H1
FontStyleItalic = &H2
FontStyleBoldItalic = &H3
FontStyleUnderline = &H4
FontStyleStrikeout = &H8
End Enum
Private Declare Function GdiplusStartup Lib "GdiPlus.dll" (ByRef mtoken As Long, ByRef mInput As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As GpStatus
Private Declare Sub GdiplusShutdown Lib "GdiPlus.dll" (ByVal mtoken As Long)
Private Declare Function GdipCreateFromHDC Lib "gdiplus" (ByVal hdc As Long, ByRef graphics As Long) As GpStatus
Private Declare Function GdipDeleteGraphics Lib "gdiplus" (ByVal mGraphics As Long) As GpStatus
Private Declare Function GdipSaveGraphics Lib "GdiPlus.dll" (ByVal mGraphics As Long, ByRef mState As Long) As GpStatus
Private Declare Function GdipRestoreGraphics Lib "GdiPlus.dll" (ByVal mGraphics As Long, ByVal mState As Long) As GpStatus
Private Declare Function GdipSetPageUnit Lib "GdiPlus.dll" (ByVal mGraphics As Long, ByRef mUnit As GpUnit) As GpStatus
Private Declare Function GdipSetPageScale Lib "GdiPlus.dll" (ByVal mGraphics As Long, ByVal mScale As Single) As GpStatus
Private Declare Function GdipGetVisibleClipBounds Lib "GdiPlus.dll" (ByVal mGraphics As Long, ByRef mRect As RECTF) As GpStatus
'Private Declare Function GdipDrawString Lib "GdiPlus.dll" (ByVal mGraphics As Long, ByVal mString As String, ByVal mLength As Long, ByVal mFont As Long, ByRef mLayoutRect As RECTF, ByVal mStringFormat As Long, ByVal mBrush As Long) As GpStatus
'Private Declare Function GdipCreateFontFamilyFromName Lib "GdiPlus.dll" (ByVal mName As String, ByVal mFontCollection As Long, ByRef mFontFamily As Long) As GpStatus
'Private Declare Function GdipCreateFont Lib "GdiPlus.dll" (ByVal mFontFamily As Long, ByVal mEmSize As Single, ByVal mStyle As FontStyle, ByRef mUnit As GpUnit, ByRef mFont As Long) As GpStatus
'Private Declare Function GdipDeleteFontFamily Lib "GdiPlus.dll" (ByVal mFontFamily As Long) As GpStatus
'Private Declare Function GdipDeleteFont Lib "GdiPlus.dll" (ByVal mFont As Long) As GpStatus
'Private Declare Function GdipCreateSolidFill Lib "GdiPlus.dll" (ByVal mColor As Long, ByRef mBrush As Long) As GpStatus
'Private Declare Function GdipDeleteBrush Lib "GdiPlus.dll" (ByVal mBrush As Long) As GpStatus
Dim token As Long
Private Sub Form_Load()
Dim inbuf As GdiplusStartupInput: inbuf.GdiplusVersion = 1
If GdiplusStartup(token, inbuf) <> OK Then
End
End If
End Sub
Private Sub Form_Paint()
'Dim br As Long
'Call GdipCreateSolidFill(Colors.Black, br)
'Dim y As Long
'y = 0
'Call DoIt(Me.hdc, br, y, UnitDisplay)
Call DoIt(Me.hdc, 0, 0, UnitPixel)
Call DoIt(Me.hdc, 0, 0, UnitDisplay)
Call DoIt(Me.hdc, 0, 0, UnitDocument)
Call DoIt(Me.hdc, 0, 0, UnitInch)
Call DoIt(Me.hdc, 0, 0, UnitMillimeter)
Call DoIt(Me.hdc, 0, 0, UnitPoint)
'Call GdipDeleteBrush(br)
End Sub
Private Sub DoIt(ByVal hdc As Long, ByVal br As Long, ByRef y As Long, ByVal unit As GpUnit)
Dim grfx As Long
Call GdipCreateFromHDC(hdc, grfx)
Dim gs As Long
Call GdipSaveGraphics(grfx, gs)
Call GdipSetPageUnit(grfx, unit)
Call GdipSetPageScale(grfx, 1)
Dim RF As RECTF
Call GdipGetVisibleClipBounds(grfx, RF)
Call GdipRestoreGraphics(grfx, gs)
Print RF.Width - RF.Left, " ", RF.Height - RF.Top
'Dim MyFont As Long
'Dim fontFamily As Long
'Call GdipCreateFontFamilyFromName(StrConv("Arial", vbUnicode), 0, fontFamily)
'Dim Sm As GpStatus
'Sm = GdipCreateFont(fontFamily, 16, FontStyleRegular, UnitPoint, MyFont)
'Call GdipDeleteFontFamily(fontFamily)
'Dim MyRect As RECTF
'MyRect.Left = 0
'MyRect.Top = y
'MyRect.Width = 300
'MyRect.Height = y + 16
'Call GdipDrawString(grfx, "Hello", 5, MyFont, MyRect, 0, br)
'Call GdipDeleteFont(MyFont)
Call GdipDeleteGraphics(grfx)
'y = MyRect.Height
End Sub
Private Sub Form_Unload(Cancel As Integer)
Call GdiplusShutdown(token)
End Sub
Вывод информации пришлось делать с помощью оператора Print, так как указать шрифт не вышло (в SM - Invalid Parameter).
Но это уже другой вопрос и для форума Vb6.
Внимание отвечающим на первый пост, тема поднята для небольшого разъяснения. Обращайте внимание на даты постов.