PrintDlg проблема с PD_ENABLESETUPHOOK

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Golart
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 14.06.2007 (Чт) 12:02

PrintDlg проблема с PD_ENABLESETUPHOOK

Сообщение Golart » 14.06.2007 (Чт) 12:15

Решил задействовать диалог PrintSetup без CommonDialog. При установке флагов в структуре PrintDlg PD_PRINTSETUP+PD_ENABLESETUPHOOK и передаче адреса hook-процедуры VB IDE падает. Посмотрел аналогичный код в VCL Delphi (компонент PrintSetupDialog) - там при таком сочетании флагов все работает. В моей hook-функции - код центрирования диалога на экране. Диалоги цвета, шрифта с такими же hook'ами работают нормально.

ЧТО ДЕЛАТЬ?Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!???

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 14.06.2007 (Чт) 12:41

А как центруешь?
Через API или методами VB?
Lasciate ogni speranza, voi ch'entrate.

Golart
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 14.06.2007 (Чт) 12:02

Сообщение Golart » 14.06.2007 (Чт) 13:02

Через API

GetSystemMetrics(X) 'ширина экрана
GetSystemMeyrics(Y)'высота экрана

GetWindowRect 'положение диалога на экране
'Вычисляю положение окна
MoveWindow

Все это происходит по WM_INITDIALOG

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 14.06.2007 (Чт) 13:23

Больше кода давай + вопрос, а в откомпилированном виде тож падает?

З.Ы. Хук для стандартных диалогов штука коварная, там есть камушки подводные
Весь мир матрица, а мы в нем потоки байтов!

Golart
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 14.06.2007 (Чт) 12:02

Сообщение Golart » 14.06.2007 (Чт) 14:29

В откомпилированном тоже падает - еще быстрее :)

Только что конвертнул на Delphi - все работает

Код: Выделить всё
Public Function ShowPrinter(ByVal hWnd As Long) As Long
Dim PrintDialog As PrintDlg   

With PrintDialog
    .hwndOwner = hWnd
    .lStructSize = Len(PrintDialog)
    .flags = PD_PRINTSETUP + PD_ENABLESETUPHOOK
    .lpfnSetupHook = GetProc(AddressOf DialogHook)
End With

ShowPrinter = PrintDlg(PrintDialog)
End Function

Private Function DialogHook(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case Msg
  Case WM_INITDIALOG
    CenterDialog hWnd
  Case Else
End Select
End Function

Private Sub CenterDialog(ByVal hWnd As Long)
Dim screenWidth As Long, screenHeight As Long
Dim dialogLeft As Long, dialogTop As Long
Dim dialogWidth As Long, dialogHeight As Long
Dim R As RECT

screenWidth = GetSystemMetrics(SM_CXSCREEN)
screenHeight = GetSystemMetrics(SM_CYSCREEN)

GetWindowRect hWnd, R

dialogHeight = R.Bottom - R.Top
dialogWidth = R.Right - R.Left

dialogLeft = (screenWidth - dialogWidth) / 2
dialogTop = (screenHeight - dialogHeight) / 3

MoveWindow hWnd, dialogLeft, dialogTop, dialogWidth, dialogHeight, Abs(True)
End Sub

Private Function GetProc(lProc As Long) As Long
  GetProc = lProc
End Function

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 14.06.2007 (Чт) 15:06

А почему процедура ничего не возвращает?
Кроме того, WM_INITDIALOG передается в диалоговое окно до того, как будет вызвана хук-процедура.
Попробуй указать DialogHook=-1 после центровки.
Lasciate ogni speranza, voi ch'entrate.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 14.06.2007 (Чт) 15:09

1. как объявлял структуру и функцию?
2. без хука падает или как?
Весь мир матрица, а мы в нем потоки байтов!

Golart
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 14.06.2007 (Чт) 12:02

Сообщение Golart » 14.06.2007 (Чт) 16:08

Вот структурка и функция

Код: Выделить всё
Private Type PRINTDLG
        lStructSize As Long
        hwndOwner As Long
        hDevMode As Long
        hDevNames As Long
        hdc As Long
        flags As Long
        nFromPage As Integer
        nToPage As Integer
        nMinPage As Integer
        nMaxPage As Integer
        nCopies As Integer
        hInstance As Long
        lCustData As Long
        lpfnPrintHook As Long
        lpfnSetupHook As Long
        lpPrintTemplateName As String
        lpSetupTemplateName As String
        hPrintTemplate As Long
        hSetupTemplate As Long
End Type

Private Declare Function PRINTDLG Lib "comdlg32.dll" Alias "PrintDlgA" (pPrintdlg As PRINTDLG) As Long


1.если поставить -1 то все равно падает
2.без хука (без флагов) - все отлично, диалог загружается

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 15.06.2007 (Пт) 7:50

WM_INITDLG, в отличии от всех остальных сообщений, поступает вначале в диалог, а только после этого в хук-процедуру. Возможно дело в этом. Попробуй сабклассить окно диалога и центровать в нем.
Lasciate ogni speranza, voi ch'entrate.

Golart
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 14.06.2007 (Чт) 12:02

Сообщение Golart » 15.06.2007 (Пт) 8:04

я сделал так:

Код: Выделить всё
Public Function ShowPrinter(ByVal hwnd As Long) As Long
   
    PrintDialog.hwndOwner = hwnd
    PrintDialog.lStructSize = Len(PrintDialog)
    'если раскомментировать эту строку то отобразится другое окно печати
    'PrintDialog.flags = PD_ENABLESETUPHOOK
    hHook = SetWindowsHookEx(WH_CBT, AddressOf CenterDialog, App.hInstance, App.ThreadID)
         
    ShowPrinter = PrintDlg(PrintDialog)
End Function

Private Function CenterDialog(ByVal lMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim R As RECT
Dim cx As Integer, cy As Integer
Dim dtop As Integer, dleft As Integer, dwidth As Integer, dheight As Integer
CenterDialog = 0
If lMsg = HCBT_ACTIVATE Then
    cx = GetSystemMetrics(SM_CXSCREEN)
    cy = GetSystemMetrics(SM_CYSCREEN)
    GetWindowRect wParam, R

    dwidth = R.Right - R.Left
    dheight = R.Bottom - R.Top

    dtop = (cy - dheight) / 3
    dleft = (cx - dwidth) / 2

    MoveWindow wParam, dleft, dtop, dwidth, dheight, Abs(True)
    UnhookWindowsHookEx hHook
    CenterDialog = -1
  End If
End Function


и все работает :)
З.Ы. в дельфях работают оба варианта

Golart
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 14.06.2007 (Чт) 12:02

Сообщение Golart » 15.06.2007 (Пт) 10:39

Если кто-нить знает еще какие-нибудь варианты, намекните, не стесняйтесь... :roll:


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 78

    TopList