@vmagnin
here is the windows procedure of the child window that first gets corrupted:
!--------------------------------------------------------------------------------------------------
!
! Darstellung von Parametern als SĂ€ulendiagramm
!
! Achtung: ttDIagramm ist fest dimensioniert.
! Wenn neue Digramme vorgesehen werden, dann ist die Dimension in WinData anzupassen.
!
!--------------------------------------------------------------------------------------------------
integer function DN_DiagrammWndProc (hWnd, iMessage, wParam, lParam)
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_DN_DiagrammWndProc@16' :: DN_DiagrammWndProc
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'DN_DiagrammWndProc' :: DN_DiagrammWndProc
!DEC$ ENDIF
use IFWIN
use DN_WinData
use DN_Data
implicit none
!**** Windows-Fenster
integer hWnd, iMessage, wParam, lParam ! Windows-Parameter
integer hDC ! Device Context
!**** Diagrammeigenschaften
integer, save :: iWinWidth, iWinHeight ! Dimensions of the Window in pixels
integer iHSmallLine ! Höhe der kleinen Schrift in Pixel
integer iHBigLine ! Höhe der groĂen Schrift in Pixel
integer iDTop, iDBottom, iDLeft, iDRight ! RÀnder der DiagrammflÀche
integer iDWidth, iDHeight ! Abmessungen der DiagrammflÀche
integer iYDist ! Abstand zwischen den y-Gitterlinien
integer iXDist ! Mittenabstand zwischen den SĂ€ulen; am Anfang und Ende jeweils eine halbe Distanz
integer iX, iY ! allgemeine Koordinaten
integer iXLeft, iXRight, iYBottom, iYTop ! Abmessingen eines zu zeichnenden Rechtecks
integer iY0 ! Position der Nullinie
integer iSWidth ! Breite einer DatensÀule
integer iXSize ! Breite eines Schriftzuges
integer :: iRand = 5 ! Rand zum Diagramm (Anordnung des Steuerbuttons
integer iBtnWidth, iBtnHeight ! Abmessungen des Steuerknopfs
integer hBtn ! Handle des Umschaltknopfs
integer, parameter :: IP_PROZENT = 2 ! Y-Achse wird in % skaliert
integer, parameter :: IP_UNIT = 1 ! Y-Achse wird in realwert skaliert
integer, dimension (3,24) :: iColor = & ! die Automatisch vergebenen Farben
reshape ((/ 0, 69,134, &
255,066,014, &
255,211,032, &
087,157,028, &
126,000,033, &
131,202,255, &
049,064,004, &
174,207,000, &
075,031,111, &
255,149,014, &
197,000,011, &
000,132,209, &
255,255,000, &
000,255,000, &
000,128,128, &
255,000,255, &
000,000,255, &
255,000,000, &
000,000,128, &
000,128,000, &
128,000,128, &
128,000,000, &
128,128,000, &
128,128,128/), (/3,24/))
integer, dimension (24) :: hBrush ! Die Pinsel zum ausfĂŒllen der SĂ€ulen
integer hNewBrush ! Pinsel mit benutzerdefinierter Farbe
logical lNewBrush ! .true. - ein benutzerdefinierter Pinsel wurde definiert
integer hOldBrush ! Handle zum originalen Pinsel
integer, save :: hBlackPen ! Handle zu einem schwarzen Stift
integer, save :: hGreyPen ! Handle zu einem grauen Stift
integer, dimension (5), save :: hUserPen ! Stift fĂŒr die Benutzerdefinierte Linien
integer hOldPen ! Handle 7zum originalen Stift
real rScal ! Skalierungsfaktor in Pixel pro Einheit
!**** Sonstiges
character*60 cRslt ! Multifunktionsstring
integer iLen ! LĂ€nge eines Strings
integer iPos ! Position des Dezimalpunkts in cRslt
integer iRslt ! multipurpose integer
integer iStyle ! Windows-Style fĂŒr Steuerknopf
integer, save, dimension (4) :: iSwitch ! Anzeiger : Darstellung in absoluten GröĂen (iProzent) oder in Prozent (iAbsolut), einer pro Diagramm
integer, parameter :: iPROZENT = 1
integer, parameter :: iABSOLUT = -1
integer iIndex ! Index des Diagramms (iiDiaEEG ...)
integer j, jj ! Schleifenparameter
integer, save :: jDCount ! DurchlaufzÀhler
logical lRslt ! multipurpose integer
logical :: lIsPaint = .false. ! Zeigt an, dass es ein Diagramm zum Zeichnen gibt.
real rRslt ! Vielzweck-Real
type (DiagramSpec) :: tDia
type (T_RECT) tRect ! Rechteck-STruktur
type (T_TEXTMETRIC) tTM ! Struktur fĂŒr Textabmessungen
type (T_PAINTSTRUCT) tPS ! Paintstruct-Struktur
type (T_SIZE) TS ! Size-Struktur
include 'resource.fd'
!--------------------------------------------------------------------------------------------------
! hier geht es los
!--------------------------------------------------------------------------------------------------
if (llDiagnose) then
if (llFirstRun) then
jDCount = 1
else
jDCount = jDCount + 1
endif
print *
print *,'Start DN_DiagrammWndProc, Aufruf Nr.:', jDCount, ' Simzeit = ', iiSimZeit
endif
select case (iMessage)
case (WM_CREATE)
!**** Abmessungen des Fensters ermitteln
lrslt = GetWindowRect (hWnd, tRect)
iWinWidth = tRect.right - tRect.Left
iWinHeight = tRect.bottom - tRect.top
!**** Umschalter Prozent/Absolut einrichten
iStyle = ior (WS_CHILD, WS_VISIBLE)
iStyle = ior (iStyle, BS_PUSHBUTTON)
hDC = CreateCompatibleDC (NULL)
lRslt = SelectObject (hDC, tDia.hSmallFont)
lRSlt = GetTextMetrics (hDC, tTM)
lRslt = DeleteDC(hDC)
iBtnHeight = tTM.tmHeight * 6 / 4
iBtnWidth = iBtnHeight
iX = iWinWidth - iRand - iBtnWidth
iY = iRand
hBtn = CreateWindow ('BUTTON','%'C, iStyle, iX, iY, iBtnWidth, iBtnHeight, hWnd,1,hhInstance,NULL)
iRslt = SendMessage (hBtn, WM_SETFONT, tDia.hSmallFont, .true.)
iSwitch = iABSOLUT ! AbsolutgröĂen als Default
!**** Pinsel vorbereiten
do j = 1,24
hBrush(j) = CreateSolidBrush (RGB (iColor (1,j), iColor (2,j), iColor (3,j)))
enddo
hBlackPen = CreatePen (PS_SOLID, 2, RGB (0,0,0))
hGreyPen = CreatePen (PS_SOLID, 1, RGB (180,180,180))
if (llDIagnose) print *,'Exit 1 DN_DIagrammWndProc'
DN_DiagrammWndProc = 0
return
case (WM_COMMAND)
if (llDiagnose) print *,'DN_DiagrammWndProc WM_COMMAND'
select case (hiword(wParam)) ! Aktionscode
case (BN_CLICKED)
iIndex = loword(wParam)
if (hWnd .eq. hhDiaEEG) iRslt = iiDIaEEG
if (hWnd .eq. hhDiaSpeicher) iRslt = iiDiaSpeicher
if (hWnd .eq. hhDiaResLast) iRslt = iiDiaResLast
if (hWnd .eq. hhDiaOptionen) iRslt = iiDiaOptionen
iSwitch (iRslt) = iSwitch (iRslt) * (-1)
lRslt = InvalidateRect (hWnd, NULL, .true.)
lRslt = UpdateWindow (hWnd)
end select
if (llDIagnose) print *,'Exit 2 DN_DIagrammWndProc'
DN_DiagrammWndProc = 0
return
case (WM_PAINT)
if (llDiagnose) print *,'DN_DiagrammWndProc WM_PAINT'
hOldPen = 0
hOldBrush = 0
!**** FenstergröĂe ermitteln
lrslt = GetWindowRect (hWnd, tRect)
iWinWidth = tRect.right - tRect.Left
iWinHeight = tRect.bottom - tRect.top
!**** Diagrammdaten auswÀhlen
if (hWnd .eq. hhDiaEEG) iIndex = iiDIaEEG
if (hWnd .eq. hhDiaSpeicher) iIndex = iiDiaSpeicher
if (hWnd .eq. hhDiaResLast) iIndex = iiDiaResLast
if (hWnd .eq. hhDiaOptionen) iIndex = iiDiaOptionen
tDia = ttDia(iIndex)
!**** Schriften und Stifte auswÀhlen
do j = 1,tDia.iNLine
hUserPen(j) = CreatePen (tDia.iLineStyle(j),tDia.iLineWidth(j),tDia.iLineColor(j))
enddo
hDC = BeginPaint (hWnd, tPS)
if (hDC .eq. 0) then
iRslt = GetLastError()
print *,'DiagrammWndProc: Error in Begin Paint. Code: ',iRslt
endif
!**** SchriftgröĂen
iRslt = SelectObject (hDC, tDia.hSmallFont)
lrslt = GetTextMetrics (hDC, tTM)
iHSmallLine = tTM.tmHeight
iRslt = SelectObject (hDC, tDia.hBigFont)
lrslt = GetTextMetrics (hDC, tTM)
iHBigLine = tTM.tmHeight
! **** Diagrammabmessungen
iDBottom = iWinHeight - iHSmallLine * 3 / 2
iDTop = (iHBigLine + iHSmallLine) * 3 / 2
iDLeft = iHSmallLine * 3 / 2 ! gleicher Rand wie unten
iDRight = iWinWidth - iHSmallLine * 3 / 2 ! gleicher Rand wie unten
iDWidth = iDRight - iDLeft
iDHeight = iDBottom - iDTop
!**** SĂ€ulen: Mittenabstand und Breiten
iXDist = nint (float (iDWidth) / float (tDia.iNValue))
iSWidth = iXDist * 7 / 10
!**** SĂ€ulen als Rechecke einzeichnen
if (iSwitch (iIndex) .eq. iPROZENT) rScal = float (iDheight) / 100.0
if (iSwitch (iIndex) .eq. iABSOLUT) rScal = float (iDheight) / (tDia.rYMax - tDia.rYMin)
! iYBottom = iDBottom
do j = 1, tDia.iNValue
if (tDIa.iColor(j) .lt. 0) then !Verwenden der vordefinierten Pinsel, wenn der User keinen ausgewÀhlt hat.
iRslt = SelectObject (hDC, hBrush(j))
lNewBrush = .false.
else
hNewBrush = CreateSolidBrush (tDia.iColor(j))
iRslt = SelectObject (hDC, hNewBrush)
if (hOldBrush .eq. 0) then
hOldBrush = iRslt
else
lRslt = DeleteObject (iRslt)
endif
lNewBrush = .true.
endif
iXLeft = iDLeft + iXDist/2 + (j - 1) * iXDist - iSWidth / 2
iXRight = iXLeft + iSWidth
iY0 = iDBottom - (0.0 - tDia.rYMin) * rScal
if (iSwitch (iIndex) .eq. iABSOLUT) then
if (tDia.rVal(j) .ge. 0.0) then
iYTop = iY0
iYBottom = iY0 - nint (tDia.rVal(j) * rScal)
else
iYTop = iY0 - nint (tDia.rVal(j) * rScal)
iYBottom = iY0
endif
endif
if (iSwitch (iIndex) .eq. iPROZENT) then ! Vorerst nur fĂŒr positive Werte definiert
rRslt = tDIa.rVal(j) / tDia.rMaxVal(j) * 100.0
iYTop = iDBottom - nint (rRslt * rScal)
iYBottom = iDBottom
endif
lRslt = MSFWIN$RectAngle (hDC, iXLeft, iYTop, iXRight, iYBottom)
if (lNewBrush) lRslt = DeleteObject (hNewBrush)
enddo
!**** Beschriftungen
!**** Titel
lRslt = SelectObject (hDC, tDia.hBigFont)
iRslt = SetTextAlign (hDC, ior(TA_BASELINE, TA_CENTER))
iX = iWinWidth / 2
iY = iHBigLine
iLen = Len_Trim (tDia.cTitle)
lRslt = Textout (hDC, iX, iY, tDia.cTitle, iLen)
!**** Zahlenwerte
lRslt = SelectObject (hDC, tDia.hSmallFont)
iY = iHBigline * 3 / 2 + iHSmallLine
do j = 1, tDia.iNValue
cRslt = ''
write (cRslt,'(f8.1)') tDia.rVal(j)
cRslt = adjustl(cRslt)
iPos = index (cRslt, '.')
if (iPos .ne. 0) cRslt (iPos:iPos) = ','
iLen = Len_Trim (cRslt)
iX = iDLeft + iXDist/2 + (j - 1) * iXDist
iRslt = TextOut(hDC, iX, iY, cRslt, iLen)
enddo
!**** Bezeichnungen der GröĂen
iY = iWinHeight - iHSmallLine / 2
do j = 1, tDia.iNValue
iLen = Len_Trim (tDia.cValName(j))
iX = iDLeft + iXDist/2 + (j - 1) * iXDist
iRslt = TextOut(hDC, iX, iY, tDia.cValName(j), iLen)
enddo
!**** Skalierung Gitternetz
iXSize = 0
iYDist = nint (float (iDHeight) / float (tDia.iNYintervals))
iRslt = SetTextAlign (hDC, ior(TA_BASELINE, TA_RIGHT))
iX = iWinWidth - iHSmallLine / 2 ! ein Wenig Abstand zum Rand, etwa wie unten
if (iSwitch(iIndex) .eq. iABSOLUT) then
do j = 1, tDia.iNYIntervals + 1
rRslt = tDia.rYMin + (j - 1) * (tDia.rYMax - tDia.rYMin) / tDia.iNYIntervals
cRslt = ''
write (cRslt,'(f8.0)') rRslt
cRslt = adjustl(cRslt)
iPos = index (cRslt, '.')
if (iPos .ne. 0) cRslt (iPos:iPos) = ','
iLen = Len_Trim (cRslt)
iY = iDBottom - (j - 1) * iYDist + iHSmallLine / 3
iRslt = TextOut(hDC, iX, iY, cRslt, iLen)
lRslt = GetTextExtentPoint32 (hDC, cRslt, iLen, TS)
iXSize = max (iXSize, TS.cx)
enddo
else if (iSwitch(iIndex) .eq. iPROZENT) then
do j = 1, 6
rRslt = (j - 1) * 20.0
cRslt = ''
write (cRslt,'(f8.0)') rRslt
cRslt = adjustl(cRslt)
iPos = index (cRslt, '.')
if (iPos .ne. 0) cRslt (iPos:iPos) = ','
iLen = Len_Trim (cRslt)
iYDist = nint (float (iDHeight) / 5.0)
iY = iDBottom - (j - 1) * iYDist + iHSmallLine / 3
iRslt = TextOut(hDC, iX, iY, cRslt, iLen)
lRslt = GetTextExtentPoint32 (hDC, cRslt, iLen, TS)
iXSize = max (iXSize, TS.cx)
enddo
endif
!**** Koordinatengitter
jj = tDia.iNYintervals + 1
if (iSwitch(iIndex) .eq. iPROZENT) jj = 6
do j = 1, jj
iRslt = SelectObject (hDC, hGreyPen)
if (hOldPen .eq. 0) hOldPen = iRslt
iY = iDBottom - (j - 1) * iYDist
lRslt = MoveToEx (hDC, iDLeft, iY, NULL)
lRSlt = MSFWIN$LineTo (hDC, iWinWidth - iXSize - iHSmallLine, iY)
enddo
!**** X-Achse
iRslt = SelectObject (hDC, hBlackPen)
if (hOldPen .eq. 0) hOldPen = iRslt
lRslt = MoveToEx (hDC, iDLeft, iY0, NULL)
lRSlt = MSFWIN$LineTo (hDC, iWinWidth - iXSize - iHSmallLine, iY0)
!**** Y-Achse
iRslt = SelectObject (hDC, hBlackPen)
iDTop = iDBottom - tDia.iNYIntervals * iYDist
lRslt = MoveToEx (hDC, iDLeft, iDBottom, NULL)
lrslt = MSFWIN$LineTo (hDC, iDLeft, iDTop)
!**** Benutzerdefinierte Linien - machen keinen Sinn in Prozentdarstellung
do j = 1, tDia.iNLine
iRslt = MSFWIN$SetTextColor (hDC, tDia.iLineColor(j))
iLen = Len_Trim (tDia.cLineText(j))
iY = iY0 - nint (tDia.rLineVal(j) * rScal) + iHSmallLine / 3
iX = iWinWidth - iHSmallLine / 2 ! ein Wenig Abstand zum Rand, etwa wie unten
iRslt = TextOut(hDC, iX, iY, tDia.cLineText(j), iLen)
lRslt = GetTextExtentPoint32 (hDC, tDia.cLineText(j), iLen, TS)
iXSize = TS.cx
iRslt = SelectObject (hDC, hUserPen(j))
if (hOldPen .eq. 0) hOldPen = iRslt
iY = iY - iHSmallLine / 3
lRslt = MoveToEx (hDC, iDLeft, iY, NULL)
iX = iWinWidth - iXSize - iHSmallLine
lRSlt = MSFWIN$LineTo (hDC, iX , iY)
enddo
if (holdBrush .ne. 0) then
iRslt = SelectObject (hDC, hOldBrush)
lrslt = DeleteObject (iRslt)
endif
if (hOldPen .ne. 0) then
iRslt = SelectObject (hDC,hOldPen)
endif
lrslt = EndPaint(hDC, tPS)
do j = 1,tDia.iNLine
lRslt = DeleteObject (hUserPen(j))
enddo
if (llDIagnose) print *,'Exit 3 DN_DIagrammWndProc'
DN_DiagrammWndProc = 0
return
case (WM_DESTROY)
if (llDiagnose) print *,'DN_DiagrammWndProc WM_DESTROY'
do j = 1, 24
lRslt = DeleteObject (hBrush(j))
enddo
lRslt = DeleteObject (hBlackPen)
lRslt = DeleteObject (hGreyPen)
if (llDIagnose) print *,'Exit 4 DN_DIagrammWndProc'
DN_DiagrammWndProc = 0
return
end select
DN_DiagrammWndProc = DefWindowProc (hWnd, iMessage, wParam, lParam)
if (llDiagnose) print *,'Exit 5 DN_DiagrammWndProc'
return
end
I tried to leave hDC just like when this procedure was started.