Public Function ShowDialog(ByVal ResName As String, pb As PictureBox) As Boolean
Dim rc As RECT, rcPic As RECT, ParentRct As RECT, ChildRct As RECT
Dim x As Long, y As Long
'Вот здесь возникает ошибка (при попытке отображения некоторых диалогов программа умирает, а всё потому,
'что функция слишком требовательна), которую я пока так и не смог решить, и
'если кто знает, огромная просьба прислать мне решение.
hDialog = CreateDialogParam(hModule, ResName, pb.hwnd, 0, 0)
If IsWindow(hDialog) Then
If GetParent(hDialog) = pb.hwnd Then
Call GetWindowRect(hDialog, rc)
Call MoveWindow(hDialog, 0, 0, rc.Right - rc.Left, rc.Bottom - rc.Top, 1)
pb.Move 0, 0, (rc.Right - rc.Left) * Screen.TwipsPerPixelX, (rc.Bottom - rc.Top + 24) * Screen.TwipsPerPixelY
Else
Call GetWindowRect(hDialog, rc)
Call GetWindowRect(pb.hwnd, rcPic)
'---------------------------------------------------
SetParent hDialog, FrmMain.PFrame.hwnd
Call GetClientRect(FrmMain.PFrame.hwnd, ParentRct)
Call GetWindowRect(hDialog, ChildRct)
x = (ParentRct.Right - ChildRct.Right + ChildRct.Left) \ 2
y = (ParentRct.Bottom - ChildRct.Bottom + ChildRct.Top) \ 2
Call MoveWindow(hDialog, x, y, ChildRct.Right - ChildRct.Left, ChildRct.Bottom - ChildRct.Top, 1)
'----------------------------------------------------------------------------------
End If
Call ShowWindow(hDialog, SW_NORMAL)
ShowDialog = True
End If
End Function
ну а на счет пойти.. скачать...найти... запустить.. разобраться ....и рассказать...... я туда не пойду, мне лично лень... если человек не может на словах объяснить суть проблемы...
Юстас писал(а):Попытка сабклассинга диалога путём указания новой DialogProc, равно как и указания DialogProc непосредственно при создании диалога приводит к одинаковому результату - программа падает.
NewProcAddr = GetWndProcAddr(AddressOf SubDlgProc)
hDialog = CreateDialogParam(hModule, ResName, pb.hwnd, NewProcAddr, 0)
NewProcAddr = GetWndProcAddr(AddressOf SubDlgProc)
OldProcAddr = SetWindowLong(hDialog, GWL_WNDPROC, NewProcAddr)
Public Function SubDlgProc(ByVal hWin As Long, uMsg As Long, wParam As Long, lParam As Long) As Long
Dim Rct As RECT
Dim MoveRect As RECT
Const WM_INITDIALOG As Long = &H110
If uMsg = WM_INITDIALOG Then
SetWindowLong hWin, 0, 1
'SubDlgProc = 1
Else
SubDlgProc = DefWindowProc(ByVal hWin, ByVal uMsg, ByVal wParam, ByVal lParam)
End If
End Function
Юстас писал(а):tyomitch
Можешь назвать хоть SukaBlaProc, суть не меняется: четыре параметра, определенные требования к возвращаемому значению при тех или иных сообщениях как в случае обработки так и пропуска сообщения. Они в основном тем и различаются, какие значения возвращаются.
Хоть SetWindowLong\GWL_WNDPROC, хоть непосредственно в CreateDialogParam указывать адрес процедуры - программа выпадает. Даже не присылая в процедуру первого сообщения - WM_INITDIALOG.
BV писал(а):А ответ желательно было бы подкрепить кодом.
Private Const WM_WINDOWPOSCHANGING = &H46
Private Type WINDOWPOS
hwnd As Long
hWndInsertAfter As Long
x As Long
y As Long
cx As Long
cy As Long
flags As Long
End Type
Private pLastWndProc As Long, sx As Long, sy As Long
Public Sub Subclass(ByVal hDialog As Long)
Static hLastDlg As Long
If hLastDlg Then SetWindowLong hLastDlg, GWL_WNDPROC, pLastWndProc
pLastWndProc = SetWindowLong(hDialog, GWL_WNDPROC, AddressOf DlgWndProc)
End Sub
Public Sub SavePosition(ByVal x As Long, ByVal y As Long)
sx = x: sy = y
End Sub
Private Function DlgWndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_WINDOWPOSCHANGING Then
Dim wp As WINDOWPOS
CopyMemory wp, ByVal lParam, Len(wp)
wp.x = sx
wp.y = sy
CopyMemory ByVal lParam, wp, Len(wp)
Else
DlgWndProc = CallWindowProc(pLastWndProc, hwnd, uMsg, wParam, lParam)
End If
End Function
hDialog = CreateDialogParam(hModule, ResName, pb.hwnd, 0, 0)
If IsWindow(hDialog) Then
If GetParent(hDialog) = pb.hwnd Then
Call GetWindowRect(hDialog, rc)
Call MoveWindow(hDialog, 0, 0, rc.Right - rc.Left, rc.Bottom - rc.Top, 1)
pb.Move 0, 0, (rc.Right - rc.Left) * Screen.TwipsPerPixelX, (rc.Bottom - rc.Top + 24) * Screen.TwipsPerPixelY
SavePosition 0, 0
Else
Call GetWindowRect(hDialog, rc)
Call GetWindowRect(pb.hwnd, rcPic)
Call MoveWindow(hDialog, rcPic.Left, rcPic.Top, rc.Right - rc.Left, rc.Bottom - rc.Top, 1)
SavePosition rcPic.Left, rcPic.Top
End If
Call ShowWindow(hDialog, SW_NORMAL)
Subclass hDialog
ShowDialog = True
End If
Public NewProcAddr As Long, OldProcAddr As Long, ChildRct As RECT
Dim X As Long, Y As Long, W As Long, H As Long
'------------------------------------------------------------------------------
Public Function ShowDialog(ByVal ResName As String, pb As PictureBox) As Boolean
Dim rc As RECT, rcPic As RECT, ParentRct As RECT
Const HWND_NOTOPMOST As Long = -2
Const SWP_NOSENDCHANGING As Long = &H400
Const SWP_NOSIZE As Long = &H1
Const SWP_SHOWWINDOW As Long = &H40
Const SWP_HIDEWINDOW As Long = &H80
hDialog = CreateDialogParam(hModule, ResName, pb.hwnd, 0, 0)
If IsWindow(hDialog) Then
If GetParent(hDialog) = pb.hwnd Then
Call GetWindowRect(hDialog, rc)
Call MoveWindow(hDialog, 0, 0, rc.Right - rc.Left, rc.Bottom - rc.Top, 1)
pb.Move 0, 0, (rc.Right - rc.Left) * Screen.TwipsPerPixelX, (rc.Bottom - rc.Top + 24) * Screen.TwipsPerPixelY
Else
Call GetWindowRect(hDialog, rc)
Call GetWindowRect(pb.hwnd, rcPic)
'---------------------------------------------------
Call GetWindowRect(FrmMain.PFrame.hwnd, ParentRct)
Call GetWindowRect(hDialog, ChildRct)
SetParent hDialog, FrmMain.PFrame.hwnd
X = (ParentRct.Right - ParentRct.Left - ChildRct.Right + ChildRct.Left) \ 2
Y = (ParentRct.Bottom - ParentRct.Top - ChildRct.Bottom + ChildRct.Top) \ 2
W = ChildRct.Right - ChildRct.Left
H = ChildRct.Bottom - ChildRct.Top
Call MoveWindow(hDialog, X, Y, W, H, 1)
'----------------------------------------------------------------------------------
End If
Call ShowWindow(hDialog, SW_NORMAL)
NewProcAddr = GetWndProcAddr(AddressOf SubDlgProc)
OldProcAddr = SetWindowLong(hDialog, GWL_WNDPROC, AddressOf SubDlgProc)
ShowDialog = True
End If
End Function
'-----------------------------------------------------------------------------
Function GetWndProcAddr(ByVal lWndProc As Long) As Long
GetWndProcAddr = lWndProc
End Function
Public Function SubDlgProc(ByVal hWin As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim wp As WINDOWPOS
Const WM_WINDOWPOSCHANGING As Long = &H46
If uMsg = WM_WINDOWPOSCHANGING Then
wp.cx = W
wp.cy = H
wp.X = X
wp.Y = Y
wp.hwnd = hWin
RtlMoveMemory ByVal lParam, wp, Len(wp)
Else
SubDlgProc = CallWindowProc(OldProcAddr, hWin, uMsg, wParam, lParam)
End If
End Function
'==============================================
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0