EgtExecutor 3.1g2 :

- sistemazioni per selezione entità in dialogo lua.
This commit is contained in:
Dario Sassi
2026-07-07 09:06:59 +02:00
parent da3fafa739
commit a14e14c641
12 changed files with 1552 additions and 925 deletions
-91
View File
@@ -1,91 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2026-2026
//----------------------------------------------------------------------------
// File : AuxDialogBox.cpp Data : 24.04.26 Versione : 3.1d4
// Contenuto : Funzioni DialogBox.
//
//
// Modifiche : 24.04.26 RE Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "EXE.h"
#include "EXE_Macro.h"
#include "AuxDialogBox.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EXeExecutor.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EgtStringConverter.h"
using namespace std ;
#pragma comment( lib, "Comctl32.lib") // per funzioni LRESULT CALLBACK
HWND phDlgModeless = nullptr ;
int nDlgModelessItem = -1 ;
//-----------------------------------------------------------------------------
bool
UpdateIdsModelessDialog( HWND phDlgModeless, int nDlgModelessItem)
{
// se DialogBox Modeless non inizializzato, esco
if ( phDlgModeless == nullptr)
return false ;
// se Id del controllo da aggiornare non valido, esco
if ( nDlgModelessItem == -1)
return false ;
// recupero tutti gli elementi selezionati
string sIds ;
int nId = ExeGetFirstSelectedObj() ;
while ( nId != GDB_ID_NULL) {
sIds.append( ToString( nId) + string{","}) ;
nId = ExeGetNextSelectedObj() ;
}
if ( ! sIds.empty())
sIds.pop_back() ;
// aggiorno il contenuto nel dialogo
return ( SetDlgItemText( phDlgModeless, nDlgModelessItem, stringtoW( sIds))) ;
}
//-----------------------------------------------------------------------------
LRESULT
CALLBACK UpdateSelectionModelessDialog( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
if ( msg == WM_GETDLGCODE)
return DLGC_WANTALLKEYS ;
if ( msg == WM_KEYDOWN && wParam == VK_RETURN) {
// dwRefData contiene l'ID dell'EDIT
int nEditId = int( dwRefData) ;
HWND hwndDlg = GetParent(hwnd) ;
if ( hwndDlg == nullptr)
return FALSE ;
// recupero il testo dell'EDIT corretto
string sIds ;
AtoWEX<128> wsEdit( "") ;
if ( GetDlgItemText( hwndDlg, nEditId, LPWSTR( wsEdit), 128) > 0)
sIds = wstrztoA( wsEdit) ;
// deseleziono tutto
ExeDeselectAll() ;
// seleziono gli ID contenuti
if ( ! sIds.empty()) {
STRVECTOR vsIds;
Tokenize( sIds, ",", vsIds) ;
for ( const string& s : vsIds) {
int nId = GDB_ID_NULL ;
if ( FromString( s, nId) && nId != GDB_ID_NULL)
ExeSelectObj( nId) ;
}
}
// aggiorno la grafica ed esco
ExeDraw() ;
return TRUE ;
}
return ( DefSubclassProc( hwnd, msg, wParam, lParam)) ;
}
-31
View File
@@ -1,31 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2026-2026
//----------------------------------------------------------------------------
// File : AuxDialogBox.h Data : 24.04.2026 Versione : 3.1d4
// Contenuto : Prototipi funzioni DialogBox.
//
//
//
// Modifiche : 22.04.26 RE Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "stdafx.h"
#include "resource.h"
#include "/EgtDev/Include/ExeExecutor.h"
#include "/EgtDev/Include/EGkLuaAux.h"
#include <shlobj.h>
//----------------------------------------------------------------------------
// Identificativo della finestra ModeLess corrente ( nullptr se non esiste)
extern HWND phDlgModeless ;
extern int nDlgModelessItem ;
// Funzione per passaggi di parametri tra Selezione DB e dialogo non modale
bool UpdateIdsModelessDialog( HWND phDlgModeless, int UpdateIdsModelessDialog) ;
//Funzione per selezionare gli Id presenti all'interno dei un EditText
LRESULT CALLBACK UpdateSelectionModelessDialog( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) ;
+16 -16
View File
@@ -15,7 +15,7 @@
#include "stdafx.h"
#include "EXE.h"
#include "EXE_Macro.h"
#include "AuxDialogBox.h"
#include "LUA_GenDialog.h"
#include "/EgtDev/Include/EXeExecutor.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EgtStringConverter.h"
@@ -71,15 +71,15 @@ ExeSelectObj( int nId)
bOk = pGeomDB->SelectObj( nId) ;
else
bOk = pGeomDB->ExistsObj( nId) ;
// eventuale aggiornamento dialogo modeless con selezione attiva
if ( bOk)
UpdateDialogIds() ;
// se richiesto, salvo il comando Lua equivalente
if ( IsCmdLog()) {
string sLua = "EgtSelectObj(" + ToString( nId) + ")" +
" -- Ok=" + ToString( bOk) ;
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
}
// verifico se presente un dialogo modeless per aggiornare i valori
if ( bOk && phDlgModeless != nullptr && nDlgModelessItem != -1)
UpdateIdsModelessDialog( phDlgModeless, nDlgModelessItem) ;
// restituisco risultato
return bOk ;
}
@@ -98,15 +98,15 @@ ExeDeselectObj( int nId)
pGseCtx->m_siSel.ResetLast() ;
else if ( nId == pGseCtx->m_siSel.nPrevId)
pGseCtx->m_siSel.ResetPrev() ;
// eventuale aggiornamento dialogo modeless con selezione attiva
if ( bOk)
UpdateDialogIds() ;
// se richiesto, salvo il comando Lua equivalente
if ( IsCmdLog()) {
string sLua = "EgtDeselectObj(" + ToString( nId) + ")" +
" -- Ok=" + ToString( bOk) ;
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
}
// verifico se presente un dialogo modeless per aggiornare i valori
if ( bOk && phDlgModeless != nullptr && nDlgModelessItem != -1)
UpdateIdsModelessDialog( phDlgModeless, nDlgModelessItem) ;
// restituisco risultato
return bOk ;
}
@@ -161,15 +161,15 @@ ExeDeselectAll( void)
bool bOk = pGeomDB->ClearSelection() ;
// reset info ultimi due selezionati
pGseCtx->m_siSel.Reset() ;
// eventuale aggiornamento dialogo modeless con selezione attiva
if ( bOk)
UpdateDialogIds() ;
// se richiesto, salvo il comando Lua equivalente
if ( IsCmdLog()) {
string sLua = "EgtDeselectAll()"
" -- Ok=" + ToString( bOk) ;
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
}
// verifico se presente un dialogo modeless per aggiornare i valori
if ( bOk && phDlgModeless != nullptr && nDlgModelessItem != -1)
UpdateIdsModelessDialog( phDlgModeless, nDlgModelessItem) ;
// restituisco risultato
return bOk ;
}
@@ -190,15 +190,15 @@ ExeSelectGroupObjs( int nGroupId)
}
else
bOk = false ;
// eventuale aggiornamento dialogo modeless con selezione attiva
if ( bOk)
UpdateDialogIds() ;
// se richiesto, salvo il comando Lua equivalente
if ( IsCmdLog()) {
string sLua = "EgtSelectGroupObjs(" + ToString( nGroupId) + ")" +
" -- Ok=" + ToString( bOk) ;
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
}
// verifico se presente un dialogo modeless per aggiornare i valori
if ( bOk && phDlgModeless != nullptr && nDlgModelessItem != -1)
UpdateIdsModelessDialog( phDlgModeless, nDlgModelessItem) ;
// restituisco risultato
return bOk ;
}
@@ -216,15 +216,15 @@ ExeDeselectGroupObjs( int nGroupId)
}
else
bOk = false ;
// eventuale aggiornamento dialogo modeless con selezione attiva
if ( bOk)
UpdateDialogIds() ;
// se richiesto, salvo il comando Lua equivalente
if ( IsCmdLog()) {
string sLua = "EgtDeselectGroupObjs(" + ToString( nGroupId) + ")" +
" -- Ok=" + ToString( bOk) ;
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
}
// verifico se presente un dialogo modeless per aggiornare i valori
if ( bOk && phDlgModeless != nullptr && nDlgModelessItem != -1)
UpdateIdsModelessDialog( phDlgModeless, nDlgModelessItem) ;
// restituisco risultato
return bOk ;
}
BIN
View File
Binary file not shown.
+183 -3
View File
@@ -222,13 +222,194 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\Include\EE3DllMain.h" />
<ClInclude Include="..\Include\EE3Export3dm.h" />
<ClInclude Include="..\Include\EE3Import3dm.h" />
<ClInclude Include="..\Include\EExBeamConst.h" />
<ClInclude Include="..\Include\EExBeamMgr.h" />
<ClInclude Include="..\Include\EExDllMain.h" />
<ClInclude Include="..\Include\EExExcExecutor.h" />
<ClInclude Include="..\Include\EExExport3MF.h" />
<ClInclude Include="..\Include\EExExportConst.h" />
<ClInclude Include="..\Include\EExExportDxf.h" />
<ClInclude Include="..\Include\EExExportStl.h" />
<ClInclude Include="..\Include\EExExportSvg.h" />
<ClInclude Include="..\Include\EExExportThreeJS.h" />
<ClInclude Include="..\Include\EExImport3MF.h" />
<ClInclude Include="..\Include\EExImportBtl.h" />
<ClInclude Include="..\Include\EExImportBtlx.h" />
<ClInclude Include="..\Include\EExImportCnc.h" />
<ClInclude Include="..\Include\EExImportCsf.h" />
<ClInclude Include="..\Include\EExImportDxf.h" />
<ClInclude Include="..\Include\EExImportOff.h" />
<ClInclude Include="..\Include\EExImportPly.h" />
<ClInclude Include="..\Include\EExImportPnt.h" />
<ClInclude Include="..\Include\EExImportStl.h" />
<ClInclude Include="..\Include\EGkArcCenTgCurvePnt.h" />
<ClInclude Include="..\Include\EGkArcPntDirTgCurve.h" />
<ClInclude Include="..\Include\EGkArcSpecial.h" />
<ClInclude Include="..\Include\EGkBBox3d.h" />
<ClInclude Include="..\Include\EGkBiArcs.h" />
<ClInclude Include="..\Include\EGkCalcPocketing.h" />
<ClInclude Include="..\Include\EGkCAvSilhouetteSurfTm.h" />
<ClInclude Include="..\Include\EGkCAvSimpleSurfFrMove.h" />
<ClInclude Include="..\Include\EGkCAvSurfFrMove.h" />
<ClInclude Include="..\Include\EGkCAvToolSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeBoxClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeClosedSurfTmClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeCylClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeSpheClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkChainCurves.h" />
<ClInclude Include="..\Include\EGkCircle2P.h" />
<ClInclude Include="..\Include\EGkCircleCenTgCurve.h" />
<ClInclude Include="..\Include\EGkColor.h" />
<ClInclude Include="..\Include\EGkCurve.h" />
<ClInclude Include="..\Include\EGkCurveArc.h" />
<ClInclude Include="..\Include\EGkCurveAux.h" />
<ClInclude Include="..\Include\EGkCurveBezier.h" />
<ClInclude Include="..\Include\EGkCurveByApprox.h" />
<ClInclude Include="..\Include\EGkCurveByInterp.h" />
<ClInclude Include="..\Include\EGkCurveComposite.h" />
<ClInclude Include="..\Include\EGkCurveLine.h" />
<ClInclude Include="..\Include\EGkCurveLocal.h" />
<ClInclude Include="..\Include\EGkCurvePointDiffGeom.h" />
<ClInclude Include="..\Include\EGkDistPointCurve.h" />
<ClInclude Include="..\Include\EGkDistPointLine.h" />
<ClInclude Include="..\Include\EGkDistPointSurfBz.h" />
<ClInclude Include="..\Include\EGkDistPointSurfFr.h" />
<ClInclude Include="..\Include\EGkDistPointSurfTm.h" />
<ClInclude Include="..\Include\EGkDllMain.h" />
<ClInclude Include="..\Include\EGkExtDimension.h" />
<ClInclude Include="..\Include\EGkExtText.h" />
<ClInclude Include="..\Include\EGkFilletChamfer.h" />
<ClInclude Include="..\Include\EGkFrame3d.h" />
<ClInclude Include="..\Include\EGkGdbConst.h" />
<ClInclude Include="..\Include\EGkGdbExecutor.h" />
<ClInclude Include="..\Include\EGkGdbIterator.h" />
<ClInclude Include="..\Include\EGkGeoCollection.h" />
<ClInclude Include="..\Include\EGkGeoConst.h" />
<ClInclude Include="..\Include\EGkGeoFrame3d.h" />
<ClInclude Include="..\Include\EGkGeomDB.h" />
<ClInclude Include="..\Include\EGkGeoObj.h" />
<ClInclude Include="..\Include\EGkGeoObjType.h" />
<ClInclude Include="..\Include\EGkGeoPoint3d.h" />
<ClInclude Include="..\Include\EGkGeoVector3d.h" />
<ClInclude Include="..\Include\EGkHashGrids1d.h" />
<ClInclude Include="..\Include\EGkHashGrids2d.h" />
<ClInclude Include="..\Include\EGkIntersCurves.h" />
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h" />
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
<ClInclude Include="..\Include\EGkIntersLinePlane.h" />
<ClInclude Include="..\Include\EGkIntersLineSurfBez.h" />
<ClInclude Include="..\Include\EGkIntersLineSurfTm.h" />
<ClInclude Include="..\Include\EGkIntersLineTria.h" />
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
<ClInclude Include="..\Include\EGkIntersPlaneSurfTm.h" />
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h" />
<ClInclude Include="..\Include\EGkIntersSurfTmSurfTm.h" />
<ClInclude Include="..\Include\EGkIntervals.h" />
<ClInclude Include="..\Include\EGkLinePerpTwoCurves.h" />
<ClInclude Include="..\Include\EGkLinePntMinDistCurve.h" />
<ClInclude Include="..\Include\EGkLinePntPerpCurve.h" />
<ClInclude Include="..\Include\EGkLinePntTgCurve.h" />
<ClInclude Include="..\Include\EGkLineTgCurvePerpCurve.h" />
<ClInclude Include="..\Include\EGkLineTgTwoCurves.h" />
<ClInclude Include="..\Include\EGkLuaAux.h" />
<ClInclude Include="..\Include\EGkMaterial.h" />
<ClInclude Include="..\Include\EGkMedialAxis.h" />
<ClInclude Include="..\Include\EGkMultiGeomDB.h" />
<ClInclude Include="..\Include\EGkObjGraphics.h" />
<ClInclude Include="..\Include\EGkOffsetCurve.h" />
<ClInclude Include="..\Include\EGkOffsetCurve3d.h" />
<ClInclude Include="..\Include\EGkPlane3d.h" />
<ClInclude Include="..\Include\EGkPoint3d.h" />
<ClInclude Include="..\Include\EGkPointGrid3d.h" />
<ClInclude Include="..\Include\EGkPolyArc.h" />
<ClInclude Include="..\Include\EGkPolygon3d.h" />
<ClInclude Include="..\Include\EGkPolygonElevation.h" />
<ClInclude Include="..\Include\EGkPolyLine.h" />
<ClInclude Include="..\Include\EGkProjectCurveSurf.h" />
<ClInclude Include="..\Include\EGkQuaternion.h" />
<ClInclude Include="..\Include\EGkSbzFromCurves.h" />
<ClInclude Include="..\Include\EGkSbzStandard.h" />
<ClInclude Include="..\Include\EGkSelection.h" />
<ClInclude Include="..\Include\EGkSfrCreate.h" />
<ClInclude Include="..\Include\EGkStmFromCurves.h" />
<ClInclude Include="..\Include\EGkStmFromTriangleSoup.h" />
<ClInclude Include="..\Include\EGkStmStandard.h" />
<ClInclude Include="..\Include\EGkStringUtils3d.h" />
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
<ClInclude Include="..\Include\EGkSurf.h" />
<ClInclude Include="..\Include\EGkSurfBezier.h" />
<ClInclude Include="..\Include\EGkSurfFlatRegion.h" />
<ClInclude Include="..\Include\EGkSurfLocal.h" />
<ClInclude Include="..\Include\EGkSurfTriMesh.h" />
<ClInclude Include="..\Include\EGkSurfTriMeshAux.h" />
<ClInclude Include="..\Include\EGkTriangle3d.h" />
<ClInclude Include="..\Include\EGkTrimming.h" />
<ClInclude Include="..\Include\EGkUiUnits.h" />
<ClInclude Include="..\Include\EGkUserObj.h" />
<ClInclude Include="..\Include\EGkUserObjFactory.h" />
<ClInclude Include="..\Include\EGkVector3d.h" />
<ClInclude Include="..\Include\EGkVolZmap.h" />
<ClInclude Include="..\Include\EGnCmdExecutor.h" />
<ClInclude Include="..\Include\EGnCmdParser.h" />
<ClInclude Include="..\Include\EGnDllMain.h" />
<ClInclude Include="..\Include\EGnEgtUUID.h" />
<ClInclude Include="..\Include\EGnFileCompare.h" />
<ClInclude Include="..\Include\EGnFileUtils.h" />
<ClInclude Include="..\Include\EGnGetKeyData.h" />
<ClInclude Include="..\Include\EGnGetModuleVer.h" />
<ClInclude Include="..\Include\EGnLuaAux.h" />
<ClInclude Include="..\Include\EGnLuaMgr.h" />
<ClInclude Include="..\Include\EGnPcInfo.h" />
<ClInclude Include="..\Include\EGnScanner.h" />
<ClInclude Include="..\Include\EGnStringKeyVal.h" />
<ClInclude Include="..\Include\EGnStringUtils.h" />
<ClInclude Include="..\Include\EGrDllMain.h" />
<ClInclude Include="..\Include\EGrImageMgr.h" />
<ClInclude Include="..\Include\EGrSceExecutor.h" />
<ClInclude Include="..\Include\EGrScene.h" />
<ClInclude Include="..\Include\EgtBase64.h" />
<ClInclude Include="..\Include\EgtFunPtrType.h" />
<ClInclude Include="..\Include\EgtILogger.h" />
<ClInclude Include="..\Include\EgtIniFile.h" />
<ClInclude Include="..\Include\EgtKeyCodes.h" />
<ClInclude Include="..\Include\EgtLibVer.h" />
<ClInclude Include="..\Include\EgtLogger.h" />
<ClInclude Include="..\Include\EgtNumCollection.h" />
<ClInclude Include="..\Include\EgtNumUtils.h" />
<ClInclude Include="..\Include\EgtPerfCounter.h" />
<ClInclude Include="..\Include\EgtPointerOwner.h" />
<ClInclude Include="..\Include\EgtStringBase.h" />
<ClInclude Include="..\Include\EgtStringConverter.h" />
<ClInclude Include="..\Include\EgtTargetVer.h" />
<ClInclude Include="..\Include\EgtTrace.h" />
<ClInclude Include="..\Include\EMkDispositionConst.h" />
<ClInclude Include="..\Include\EMkDllMain.h" />
<ClInclude Include="..\Include\EMkMachiningConst.h" />
<ClInclude Include="..\Include\EMkMachiningGeoConst.h" />
<ClInclude Include="..\Include\EMkMachMgr.h" />
<ClInclude Include="..\Include\EMkOperationConst.h" />
<ClInclude Include="..\Include\EMkSimuGenConst.h" />
<ClInclude Include="..\Include\EMkToolConst.h" />
<ClInclude Include="..\Include\ENkCplxCollection.h" />
<ClInclude Include="..\Include\ENkDllMain.h" />
<ClInclude Include="..\Include\ENkMachOptimization.h" />
<ClInclude Include="..\Include\ENkMaximumFiller.h" />
<ClInclude Include="..\Include\ENkPolynomialRoots.h" />
<ClInclude Include="..\Include\ENkShortestPath.h" />
<ClInclude Include="..\Include\ENmLuaAux.h" />
<ClInclude Include="..\Include\ENsAutoNester.h" />
<ClInclude Include="..\Include\ENsDllMain.h" />
<ClInclude Include="..\Include\EXeCmdLogOff.h" />
<ClInclude Include="..\Include\EXeConst.h" />
<ClInclude Include="..\Include\EXeDllMain.h" />
<ClInclude Include="..\Include\EXeExecutor.h" />
<ClInclude Include="AuxDialogBox.h" />
<ClInclude Include="LUA_GenDialog.h" />
<ClInclude Include="DllExch3dm.h" />
<ClInclude Include="DllMain.h" />
<ClInclude Include="DllNesting.h" />
@@ -250,7 +431,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="AuxDialogBox.cpp" />
<ClCompile Include="DllExch3dm.cpp" />
<ClCompile Include="DllNesting.cpp" />
<ClCompile Include="EXE_Base64.cpp" />
@@ -307,7 +487,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="DllMachKernel.cpp" />
<ClCompile Include="EXeDllMain.cpp" />
<ClCompile Include="EXE_UiUnits.cpp" />
<ClCompile Include="GenTools.cpp" />
<ClCompile Include="GeoTools.cpp" />
<ClCompile Include="GseContext.cpp" />
<ClCompile Include="LUA_Base64.cpp" />
@@ -319,6 +498,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="LUA_GdbGetPocketing.cpp" />
<ClCompile Include="LUA_GdbGetSurf.cpp" />
<ClCompile Include="LUA_GdbGetVol.cpp" />
<ClCompile Include="LUA_GenDialog.cpp" />
<ClCompile Include="LUA_GeoDist.cpp" />
<ClCompile Include="LUA_GeoInters.cpp" />
<ClCompile Include="LUA_MachOpt.cpp" />
+546 -6
View File
@@ -111,9 +111,552 @@
<ClInclude Include="DllExch3dm.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="AuxDialogBox.h">
<ClInclude Include="LUA_GenDialog.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="..\Include\EE3DllMain.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EE3Export3dm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EE3Import3dm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExBeamConst.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExBeamMgr.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExDllMain.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExExcExecutor.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExExport3MF.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExExportConst.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExExportDxf.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExExportStl.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExExportSvg.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExExportThreeJS.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExImport3MF.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExImportBtl.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExImportBtlx.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExImportCnc.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExImportCsf.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExImportDxf.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExImportOff.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExImportPly.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExImportPnt.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EExImportStl.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkArcCenTgCurvePnt.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkArcPntDirTgCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkArcSpecial.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkBBox3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkBiArcs.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCalcPocketing.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCAvSilhouetteSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCAvSimpleSurfFrMove.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCAvSurfFrMove.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCAvToolSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCDeBoxClosedSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCDeClosedSurfTmClosedSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCDeCylClosedSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCDeSpheClosedSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkChainCurves.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCircle2P.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCircleCenTgCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkColor.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCurveArc.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCurveAux.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCurveBezier.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCurveByApprox.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCurveByInterp.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCurveComposite.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCurveLine.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkCurvePointDiffGeom.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkDistPointCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkDistPointLine.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkDistPointSurfBz.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkDistPointSurfFr.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkDistPointSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkDllMain.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkExtDimension.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkExtText.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkFilletChamfer.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkFrame3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkGdbConst.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkGdbExecutor.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkGdbIterator.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkGeoCollection.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkGeoConst.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkGeoFrame3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkGeoObj.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkGeoObjType.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkGeoPoint3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkGeoVector3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkHashGrids1d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkHashGrids2d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersCurves.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersLineBox.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersLinePlane.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersLineSurfBez.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersLineSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersLineTria.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersPlaneBox.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersPlaneSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersSurfTmSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntervals.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLinePerpTwoCurves.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLinePntMinDistCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLinePntPerpCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLinePntTgCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLineTgCurvePerpCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLineTgTwoCurves.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLuaAux.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkMaterial.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkMedialAxis.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkMultiGeomDB.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkObjGraphics.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkOffsetCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkOffsetCurve3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkPlane3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkPoint3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkPointGrid3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkPolyArc.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkPolygon3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkPolygonElevation.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkPolyLine.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkProjectCurveSurf.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkQuaternion.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSbzFromCurves.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSbzStandard.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSelection.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSfrCreate.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkStmFromCurves.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkStmFromTriangleSoup.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkStmStandard.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkStringUtils3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSurf.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSurfBezier.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSurfFlatRegion.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSurfLocal.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSurfTriMesh.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSurfTriMeshAux.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkTriangle3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkTrimming.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkUiUnits.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkUserObj.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkUserObjFactory.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkVector3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkVolZmap.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnCmdExecutor.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnCmdParser.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnDllMain.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnEgtUUID.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnFileCompare.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnFileUtils.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnGetKeyData.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnGetModuleVer.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnLuaAux.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnLuaMgr.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnPcInfo.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnScanner.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnStringKeyVal.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGnStringUtils.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGrDllMain.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGrImageMgr.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGrSceExecutor.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGrScene.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtBase64.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtFunPtrType.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtILogger.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtIniFile.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtKeyCodes.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtLibVer.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtLogger.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtNumCollection.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtNumUtils.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtPerfCounter.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtPointerOwner.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtStringBase.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtStringConverter.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtTargetVer.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EgtTrace.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EMkDispositionConst.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EMkDllMain.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EMkMachiningConst.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EMkMachiningGeoConst.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EMkMachMgr.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EMkOperationConst.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EMkSimuGenConst.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EMkToolConst.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\ENkCplxCollection.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\ENkDllMain.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\ENkMachOptimization.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\ENkMaximumFiller.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\ENkPolynomialRoots.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\ENkShortestPath.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\ENmLuaAux.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\ENsAutoNester.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\ENsDllMain.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="LUA_Exchange.cpp">
@@ -305,9 +848,6 @@
<ClCompile Include="LUA_GdbModifyVol.cpp">
<Filter>File di origine\LUA</Filter>
</ClCompile>
<ClCompile Include="GenTools.cpp">
<Filter>File di origine\Global</Filter>
</ClCompile>
<ClCompile Include="EXE_Image.cpp">
<Filter>File di origine\EXE</Filter>
</ClCompile>
@@ -434,8 +974,8 @@
<ClCompile Include="LUA_Base64.cpp">
<Filter>File di origine\LUA</Filter>
</ClCompile>
<ClCompile Include="AuxDialogBox.cpp">
<Filter>File di origine\Global</Filter>
<ClCompile Include="LUA_GenDialog.cpp">
<Filter>File di origine\LUA</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
-56
View File
@@ -1,56 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2017-2017
//----------------------------------------------------------------------------
// File : GenTools.cpp Data : 08.01.17 Versione : 1.6x5
// Contenuto : Funzioni generalie.
//
//
//
// Modifiche : 08.01.17 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
#include "stdafx.h"
#include "GenTools.h"
#include <utility>
using namespace std ;
//----------------------------------------------------------------------------
HWND
FindTopWindow( void)
{
// Recupero l'Id del processo corrente
DWORD pid = GetCurrentProcessId() ;
pair<HWND, DWORD> params = { 0, pid} ;
// Enumerate the windows using a lambda to process each window
SetLastError( 0) ;
BOOL bResult = EnumWindows( []( HWND hWnd, LPARAM lParam) -> BOOL
{
auto pParams = ( pair<HWND, DWORD>*)(lParam) ;
DWORD processId ;
if ( GetWindowThreadProcessId( hWnd, &processId) != NULL &&
processId == pParams->second &&
GetWindow( hWnd, GW_OWNER) == NULL &&
IsWindowVisible( hWnd)) {
// Stop enumerating
SetLastError( -1) ;
pParams->first = hWnd ;
return FALSE ;
}
// Continue enumerating
return TRUE ;
}, (LPARAM) &params) ;
if ( ! bResult && GetLastError() == -1 && params.first != nullptr) {
return params.first ;
}
return nullptr ;
}
-22
View File
@@ -1,22 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2017-2017
//----------------------------------------------------------------------------
// File : GenTools.h Data : 08.01.17 Versione : 1.6x5
// Contenuto : Prototipi funzioni generiche.
//
//
//
// Modifiche : 08.01.17 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#define NOMINMAX
#include <windows.h>
//----------------------------------------------------------------------------
// Recupero l'handle della finestra principale dell'eseguibile
HWND FindTopWindow( void) ;
+780
View File
@@ -0,0 +1,780 @@
//----------------------------------------------------------------------------
// EgalTech 2026-2026
//----------------------------------------------------------------------------
// File : LUA_GenDialog.cpp Data : 06.07.26 Versione : 3.1g2
// Contenuto : Funzioni gestione dialoghi per LUA.
//
//
//
// Modifiche : 06.07.26 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "DllMain.h"
#include "EXE.h"
#include "LUA.h"
#include "LUA_GenDialog.h"
#include "resource.h"
#include "/EgtDev/Include/ExeExecutor.h"
#include "/EgtDev/Include/EGkLuaAux.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EgtIniFile.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include <Windowsx.h>
#include <shlobj.h>
using namespace std ;
//----------------------------------------------------------------------------
// Costanti
const int MAX_CTRLS = IDC_TEXT8 - IDC_TEXT1 + 1 ;
const int OFFS_CTRLS = 40 ;
enum TYPE_CTRLS { CTRL_NONE = 0, CTRL_CHECK = 1, CTRL_COMBO = 2, CTRL_EDIT = 3, CTRL_COLOR = 4, CTRL_BUTTON = 5} ;
const char* SEC_SCENE = "Scene" ;
const char* KEY_CUSTOMCOLORS = "CustomColors" ;
// Tipi
struct DialogContext {
bool bDone = false ; // flag per chiusura dialogo (X/Ok/Cancel)
bool bCancelled = false ; // true se X/Cancel
STRVECTOR vsResult ; // valori finali da ritornare a Lua
} ;
// Variabili Globali
static COLORREF s_CustomColors[16] = {12632256} ; // 16 colori GRAY
static bool s_bCustomColorsInit = false ; // flag di inizializzazione colori
static HWND s_hDlg = NULL ;
static string s_sCaption ;
static int s_nCtrls = 0 ;
static string s_sText[MAX_CTRLS] ;
static string s_sEdit[MAX_CTRLS] ;
static int s_nType[MAX_CTRLS] ;
static bool s_bSelectionMode = false ; // se true allora diventa dialogo "Modeless"
static int s_nActiveRow = - 1 ; // indice della riga di "SB:" attiva
static int s_nDlgItem = -1 ; // indice dell'Item di selezione
//-------------------------------------------------------------------------------
// OnClosingDialog
//
// Scopo:
// Gestisce la chiusura del dialogo modeless in modo centralizzato e sicuro.
// Questa funzione viene chiamata quando lutente chiude il dialogo tramite:
// - OK
// - Cancel
// - pulsante X
// - WM_CLOSE
//
// Comportamento:
// - Riabilita la finestra principale (Main Window), che era stata disabilitata durante il funzionamento
// modale del dialogo.
// - Distrugge la finestra del dialogo.
// - Riporta il focus alla finestra principale, garantendo continuità nellinterazione dellutente.
// - Deseleziona tutti gli oggetti nella scena e aggiorna la vista, in modo che nessuna selezione residua
// rimanga attiva dopo la chiusura.
//-------------------------------------------------------------------------------
static void
OnClosingDialog( HWND hwndDlg)
{
// reset stato globale
s_bSelectionMode = false ;
s_nActiveRow = -1 ;
s_nDlgItem = -1 ;
// il controllo passa al Main
HWND hMain = GetParent( hwndDlg) ;
EnableWindow( hMain, TRUE) ;
DestroyWindow( hwndDlg) ;
s_hDlg = NULL ;
SetFocus( hMain) ;
// deseleziono tutto
ExeDeselectAll() ;
ExeDraw() ;
}
//-------------------------------------------------------------------------------
// StartSelectionMode
//
// Scopo:
// Attiva la modalità di selezione (modeless) del dialogo. Questa modalità permette allutente di interagire
// con la scena mentre il dialogo rimane aperto e attivo.
//
// Parametri:
// hDlg → handle del dialogo
// nEditId → ID delledit associato al pulsante BS premuto
// nActiveRow → indice della riga BS attiva (0..MAX_CTRLS-1)
//-------------------------------------------------------------------------------
static void
StartSelectionMode( HWND hDlg, int nEditId, int nActiveRow)
{
// il dialogo torna modeless rispetto alla scena
HWND hMain = GetParent( hDlg) ;
EnableWindow( hMain, TRUE) ;
// resta comunque in primo piano
SetWindowPos( hDlg, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) ;
// disabilito tutti gli edit associati agli SB tranne quello attivo
for ( int i = 0; i < s_nCtrls ; ++ i) {
if ( s_sEdit[i].find( "SB:") == 0) {
int idEdit = IDC_EDIT1 + i ;
EnableWindow( GetDlgItem( hDlg, idEdit), ( i == nActiveRow ? TRUE : FALSE)) ;
}
}
// seleziono solo gli elementi presenti nell'edit corrispondente
s_nDlgItem = - 1 ;
ExeDeselectAll() ; // !<-- NB. avendo messo s_nDlgItem = -1 il testo non viene rimosso
s_bSelectionMode = true ;
s_nActiveRow = nActiveRow ;
s_nDlgItem = nEditId ;
AtoWEX<128> wsEdit( "") ;
GetDlgItemText( hDlg, nEditId, LPWSTR( wsEdit), 128) ;
string sIds = wstrztoA( wsEdit) ;
STRVECTOR vsIds ;
Tokenize( sIds, ",", vsIds) ;
for ( const string& sId : vsIds) {
int nId = GDB_ID_NULL ;
if ( FromString( sId, nId) && nId != GDB_ID_NULL)
ExeSelectObj( nId) ;
}
ExeDraw() ;
}
//-------------------------------------------------------------------------------
// EndSelectionMode
//
// Scopo:
// Termina la modalità di selezione e riporta il dialogo in stato modale.
//-------------------------------------------------------------------------------
static void
EndSelectionMode( HWND hDlg)
{
s_bSelectionMode = false ;
s_nActiveRow = -1 ;
s_nDlgItem = -1 ;
// disabilito tutti gli edit associati ai BS
for ( int i = 0; i < s_nCtrls ; ++ i) {
if ( s_sEdit[i].find( "SB:") == 0) {
int idEdit = IDC_EDIT1 + i ;
EnableWindow( GetDlgItem( hDlg, idEdit), FALSE) ;
SetDlgItemText( hDlg, IDC_BUTTON_SEL1 + i, strztoW( "+")) ;
}
}
// il dialogo torna modale
HWND hMain = GetParent( hDlg) ;
EnableWindow( hMain, FALSE) ;
SetFocus( hDlg) ;
// deseleziono tutto
ExeDeselectAll() ; //!<-- NB. avendo messo nDlgModelessItem = -1 il testo non viene rimosso
ExeDraw() ;
}
//-----------------------------------------------------------------------------
LRESULT
CALLBACK UpdateDialogSelection( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
if ( msg == WM_GETDLGCODE)
return DLGC_WANTALLKEYS ;
if ( msg == WM_KEYDOWN && wParam == VK_RETURN) {
// dwRefData contiene l'ID dell'EDIT
int nEditId = int( dwRefData) ;
HWND hwndDlg = GetParent(hwnd) ;
if ( hwndDlg == nullptr)
return FALSE ;
// recupero il testo dell'EDIT corretto
string sIds ;
AtoWEX<128> wsEdit( "") ;
if ( GetDlgItemText( hwndDlg, nEditId, LPWSTR( wsEdit), 128) > 0)
sIds = wstrztoA( wsEdit) ;
// deseleziono tutto
ExeDeselectAll() ;
// seleziono gli ID contenuti
if ( ! sIds.empty()) {
STRVECTOR vsIds;
Tokenize( sIds, ",", vsIds) ;
for ( const string& s : vsIds) {
int nId = GDB_ID_NULL ;
if ( FromString( s, nId) && nId != GDB_ID_NULL)
ExeSelectObj( nId) ;
}
}
// aggiorno la grafica ed esco
ExeDraw() ;
return TRUE ;
}
return ( DefSubclassProc( hwnd, msg, wParam, lParam)) ;
}
//-------------------------------------------------------------------------------
BOOL
CALLBACK DialogBoxProc( HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
// variabili static locali per mantenere lo stato tra chiamate per selezione colori
static COLORREF selectedColor[MAX_CTRLS] = {0} ; // BLACK
static HBRUSH hColorBrush[MAX_CTRLS] = {NULL} ; // non definito
switch ( message) {
case WM_INITDIALOG :
{
// imposto il dialogo come modale
HWND hMain = GetParent( hwndDlg) ;
EnableWindow( hMain, FALSE) ;
SetFocus( hwndDlg) ;
// imposto il contesto della funzione per recuperalo in futuro (per la funzione di CallBack Lua)
SetWindowLongPtr( hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam) ;
// colore di default
COLORREF defaultColor = RGB( 255, 0, 0) ;
// inizializzazione colori e brush
for ( int i = 0 ; i < MAX_CTRLS ; ++ i) {
selectedColor[i] = defaultColor ;
if ( hColorBrush[i] != NULL)
DeleteObject( hColorBrush[i]) ;
hColorBrush[i] = CreateSolidBrush( selectedColor[i]) ;
}
// dati del dialogo
HWND hwndOwner = GetParent( hwndDlg) ;
if ( hwndOwner == nullptr)
hwndOwner = GetDesktopWindow() ;
RECT rcOwner, rcDlg ;
GetWindowRect( hwndOwner, &rcOwner) ;
GetWindowRect( hwndDlg, &rcDlg) ;
// determino la posizione dell'ultima riga di dati da visualizzare
HWND hwndLR = GetDlgItem( hwndDlg, IDC_TEXT1 + Clamp( s_nCtrls, 1, MAX_CTRLS) - 1) ;
RECT rcLR ;
GetWindowRect( hwndLR, &rcLR) ;
POINT ptLR{ rcLR.left, rcLR.top} ;
ScreenToClient( hwndDlg, &ptLR) ;
// centro e scalo il dialogo
int nNewH = rcLR.top - rcOwner.top + 2 * OFFS_CTRLS ; // non chiaro perchè va sottratto rcOwner.top ma funziona sempre
SetWindowPos( hwndDlg, HWND_TOP,
( rcOwner.left + rcOwner.right - ( rcDlg.right - rcDlg.left)) / 2,
( rcOwner.top + rcOwner.bottom - nNewH) / 2,
( rcDlg.right - rcDlg.left),
nNewH, 0) ;
// riposiziono il bottone Ok
HWND hwndOk = GetDlgItem( hwndDlg, IDOK) ;
RECT rcOk ;
GetWindowRect( hwndOk, &rcOk) ;
POINT ptOk{ rcOk.left, rcOk.top} ;
ScreenToClient( hwndDlg, &ptOk) ;
SetWindowPos( hwndOk, hwndDlg, ptOk.x, ptLR.y + OFFS_CTRLS, 0, 0, SWP_NOSIZE | SWP_NOZORDER) ;
// riposiziono il bottone Cancel
HWND hwndCl = GetDlgItem( hwndDlg, IDCANCEL) ;
RECT rcCl ;
GetWindowRect( hwndCl, &rcCl) ;
POINT ptCl{ rcCl.left, rcCl.top} ;
ScreenToClient( hwndDlg, &ptCl) ;
SetWindowPos( hwndCl, hwndDlg, ptCl.x, ptLR.y + OFFS_CTRLS, 0, 0, SWP_NOSIZE | SWP_NOZORDER) ;
// stile finestra
LONG style = GetWindowLong( hwndDlg, GWL_STYLE) ;
style |= WS_SYSMENU ;
SetWindowLong( hwndDlg, GWL_STYLE, style) ;
}
// assegno titolo del dialogo
SetWindowText( hwndDlg, stringtoW( s_sCaption)) ;
// assegno testi e valori di default e nascondo linee dei controlli non usati
for ( int i = 0 ; i < MAX_CTRLS ; ++ i) {
if ( i < s_nCtrls) {
// imposto il testo nella riga corrente
SetDlgItemText( hwndDlg, IDC_TEXT1 + i, stringtoW( s_sText[i])) ;
// --- se CheckBox
if ( s_sEdit[i].find( "CK:") == 0) {
bool bChecked = false ;
FromString( s_sEdit[i].substr( 3), bChecked) ;
CheckDlgButton( hwndDlg, IDC_CHECK1 + i, ( bChecked ? BST_CHECKED : BST_UNCHECKED)) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_EDIT1 + i), SW_HIDE) ; // nascondo Edit
ShowWindow( GetDlgItem( hwndDlg, IDC_COMBO1 + i), SW_HIDE) ; // nascondo Combo
ShowWindow( GetDlgItem( hwndDlg, IDC_BUTTON_SEL1 + i), SW_HIDE) ; // nascondo Button di selezione
s_nType[i] = CTRL_CHECK ;
}
// --- se ComboBox
else if ( s_sEdit[i].find( "CB:") == 0) {
string sList = s_sEdit[i].substr( 3) ;
STRVECTOR vsVal ;
Tokenize( sList, ",", vsVal) ;
int nSel = 0 ;
HWND hwndCBox = GetDlgItem( hwndDlg, IDC_COMBO1 + i) ;
for ( int j = 0 ; j < ssize( vsVal) ; ++ j) {
string sItem ;
if ( vsVal[j][0] == '*') {
nSel = j ;
sItem = vsVal[j].substr( 1) ;
}
else
sItem = vsVal[j] ;
ComboBox_AddString( hwndCBox, stringtoW( sItem)) ;
}
ComboBox_SetCurSel( hwndCBox, nSel) ;
int nEditHeight = int( SendMessage( hwndCBox, CB_GETITEMHEIGHT, (WPARAM)-1, 0)) ;
int nItemHeight = int( SendMessage( hwndCBox, CB_GETITEMHEIGHT, 0, 0)) ;
int nTotalHeight = nEditHeight + nItemHeight * ( ssize( vsVal) + 1) ;
RECT rc ; GetWindowRect( hwndCBox, &rc) ;
HWND parent = GetParent(hwndCBox) ; MapWindowPoints( NULL, parent, (LPPOINT)&rc, 2) ;
SetWindowPos( hwndCBox, NULL, rc.left, rc.top, rc.right - rc.left, nTotalHeight, SWP_NOZORDER) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_EDIT1 + i), SW_HIDE) ; // nascondo Edit
ShowWindow( GetDlgItem( hwndDlg, IDC_CHECK1 + i), SW_HIDE) ; // nascondo CheckBox
ShowWindow( GetDlgItem( hwndDlg, IDC_BUTTON_SEL1 + i), SW_HIDE) ; // nascondo Button di selezione
s_nType[i] = CTRL_COMBO ;
}
// --- se ColorPicker
else if ( s_sEdit[i].find( "CP:") == 0) {
string sVal = s_sEdit[i].substr( 3) ;
Color CColor ;
if ( ! FromString( sVal, CColor))
CColor = INVISIBLE ;
selectedColor[i] = RGB( CColor.GetIntRed(), CColor.GetIntGreen(), CColor.GetIntBlue()) ;
if ( hColorBrush[i] != NULL)
DeleteObject( hColorBrush[i]) ;
hColorBrush[i] = CreateSolidBrush( selectedColor[i]) ;
// recupero i valori dei colori personalizzati dal file .ini
if ( ! s_bCustomColorsInit) {
// recupero il file Ini
string sIniFile = ExeGetIniFile() ;
if ( ! sIniFile.empty()) {
string sCustomVals = GetPrivateProfileStringUtf8( SEC_SCENE, KEY_CUSTOMCOLORS, "", sIniFile.c_str()) ;
STRVECTOR vsWinColors ; Tokenize( sCustomVals, ",", vsWinColors) ;
for ( int j = 0 ; j < ssize( vsWinColors) && j < 16 ; ++ j) {
unsigned int unVal ;
if ( FromString( vsWinColors[j], unVal)) {
unsigned int unR = unVal & 0xFF ;
unsigned int unG = ( unVal >> 8) & 0xFF ;
unsigned int unB = ( unVal >> 16) & 0xFF ;
s_CustomColors[j] = RGB( unR, unG, unB) ;
}
}
}
s_bCustomColorsInit = true ;
}
// nascondo qualsiasi tipo di componente
ShowWindow( GetDlgItem( hwndDlg, IDC_EDIT1 + i), SW_HIDE) ; // nascondo Edit
ShowWindow( GetDlgItem( hwndDlg, IDC_COMBO1 + i), SW_HIDE) ; // nascondo Combo
ShowWindow( GetDlgItem( hwndDlg, IDC_CHECK1 + i), SW_HIDE) ; // nascondo Check
ShowWindow( GetDlgItem( hwndDlg, IDC_BUTTON_SEL1 + i), SW_HIDE) ; // nascondo Button di selezione
// margini per dimensione del rettangolo preview pickColor
const int PREVIEW_HEIGHT = 20 ; // altezza del rettangolo
const int PREVIEW_MIN_WIDTH = 40 ; // larghezza minima
// creazione della static preview
HWND hwndPreview = NULL ;
HWND hwndEdit = GetDlgItem( hwndDlg, IDC_EDIT1 + i) ;
RECT rcEdit ; GetClientRect( hwndDlg, &rcEdit) ; // coordinate client del dialog
if ( hwndEdit != nullptr && GetWindowRect( hwndEdit, &rcEdit)) {
// converti rcLabel in coordinate client
POINT ptEdit = { rcEdit.left, rcEdit.top } ;
ScreenToClient( hwndDlg, &ptEdit) ;
int x = ptEdit.x ;
int y = ptEdit.y ;
int width = rcEdit.right - rcEdit.left ;
if ( width < PREVIEW_MIN_WIDTH)
width = PREVIEW_MIN_WIDTH ;
hwndPreview = CreateWindowEx( 0, L"STATIC", NULL,
WS_CHILD | WS_VISIBLE | SS_NOTIFY | SS_CENTERIMAGE | WS_BORDER,
x, y, width, PREVIEW_HEIGHT,
hwndDlg, ( HMENU)INT_PTR( IDC_COLOR1 + i),
GetModuleHandle( NULL), NULL) ;
}
// pulizia elementi testuali
if ( hwndPreview) {
SetWindowText( hwndPreview, L"") ;
SetWindowPos( hwndPreview, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) ;
InvalidateRect( hwndPreview, NULL, TRUE) ;
UpdateWindow( hwndPreview) ;
}
s_nType[i] = CTRL_COLOR ;
}
// --- se Button di selezione
else if ( s_sEdit[i].find( "SB:") == 0) {
ShowWindow( GetDlgItem( hwndDlg, IDC_COMBO1 + i), SW_HIDE) ; // nascondo la Combo
ShowWindow( GetDlgItem( hwndDlg, IDC_CHECK1 + i), SW_HIDE) ; // nascondo la Check
SetDlgItemText( hwndDlg, IDC_BUTTON_SEL1 + i, strztoW( "+")) ; // modalità non Selezione
EnableWindow( GetDlgItem( hwndDlg, IDC_EDIT1 + i), FALSE) ; // disattivo la Edit
// associo alla casella di testo la funzione di KeyPress su Enter
HWND hEdit = GetDlgItem( hwndDlg, IDC_EDIT1 + i) ;
if ( hEdit != nullptr)
SetWindowSubclass( hEdit, UpdateDialogSelection, 1, (DWORD_PTR)( IDC_EDIT1 + i)) ;
s_nType[i] = CTRL_BUTTON ;
}
// --- se Testo
else {
SetDlgItemText( hwndDlg, IDC_EDIT1 + i, stringtoW( s_sEdit[i])) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_COMBO1 + i), SW_HIDE) ; // nascondo Combo
ShowWindow( GetDlgItem( hwndDlg, IDC_CHECK1 + i), SW_HIDE) ; // nascondo Check
ShowWindow( GetDlgItem( hwndDlg, IDC_BUTTON_SEL1 + i), SW_HIDE) ; // nascondo Button di selezione
s_nType[i] = CTRL_EDIT ;
}
}
// se numero di controllo superiore al massimo, non visualizzo nullo ( in questo caso aggiungere elementi a Dialog in .rc)
else {
// nascondo tutto
ShowWindow( GetDlgItem( hwndDlg, IDC_TEXT1 + i), SW_HIDE) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_EDIT1 + i), SW_HIDE) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_COMBO1 + i), SW_HIDE) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_CHECK1 + i), SW_HIDE) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_BUTTON_SEL1 + i), SW_HIDE) ;
s_nType[i] = CTRL_NONE ;
}
}
break ;
case WM_CTLCOLORSTATIC :
{
HDC hdcStatic = ( HDC)wParam ;
HWND hwndCtrl = ( HWND)lParam ;
int ctrlId = GetDlgCtrlID( hwndCtrl) ;
if ( ctrlId >= IDC_COLOR1 && ctrlId <= IDC_COLOR8) {
int idx = ctrlId - IDC_COLOR1 ;
if ( hColorBrush[idx] == NULL)
hColorBrush[idx] = CreateSolidBrush( selectedColor[idx]) ;
SetBkMode( hdcStatic, OPAQUE) ;
SetBkColor( hdcStatic, selectedColor[idx]) ;
return ( INT_PTR)hColorBrush[idx] ;
}
}
break ;
case WM_COMMAND :
{
int id = LOWORD( wParam) ;
int code = HIWORD( wParam) ;
// --- se click di un Button di selezione
if ( id >= IDC_BUTTON_SEL1 && id < IDC_BUTTON_SEL1 + MAX_CTRLS) {
int nBtnId = id ;
int nEditId = IDC_EDIT1 + ( id - IDC_BUTTON_SEL1) ;
int nActiveRow = nEditId - IDC_EDIT1 ;
// se il bottone premuto è lo stesso
if ( s_nDlgItem == nEditId) {
// se selezione attiva, allora deve terminare
if ( s_bSelectionMode) {
SetDlgItemText( hwndDlg, nBtnId, strztoW( "+")) ;
EndSelectionMode( hwndDlg) ;
}
// se selezione non attiva, allora viene attivata
else {
SetDlgItemText( hwndDlg, nBtnId, strztoW( "S")) ;
StartSelectionMode( hwndDlg, nEditId, nActiveRow) ;
}
}
// se nuovo buttone premuto
else {
// se esisteva una selezione precedente, questa viene annullata
if ( s_nDlgItem != -1) {
// recupero il Button di selezione precedente e modifico il suo testo
int nPrevBtnId = IDC_BUTTON_SEL1 + ( s_nDlgItem - IDC_EDIT1) ;
SetDlgItemText( hwndDlg, nPrevBtnId, strztoW( "+")) ;
}
// la selezione passa al comando corrente
s_nDlgItem = nEditId ;
SetDlgItemText( hwndDlg, nBtnId, strztoW( "S")) ;
// il dialogo diventa "Modeless" temporaneamente
s_nActiveRow = nEditId - IDC_EDIT1 ;
StartSelectionMode( hwndDlg, nEditId, nActiveRow) ;
}
return TRUE ; // !<-- esco
}
// --- se comando di Preview per brush di colori mediante click del mouse
else if ( code == STN_CLICKED && id >= IDC_COLOR1 && id <= IDC_COLOR8) {
// se selezione attiva, allora deve terminare
if ( s_bSelectionMode) {
// se esisteva una selezione precedente, questa viene annullata
if ( s_nDlgItem != -1) {
// recupero il Button di selezione precedente e modifico il suo testo
int nPrevBtnId = IDC_BUTTON_SEL1 + ( s_nDlgItem - IDC_EDIT1) ;
SetDlgItemText( hwndDlg, nPrevBtnId, strztoW( "+")) ;
}
EndSelectionMode( hwndDlg) ;
}
int idx = id - IDC_COLOR1 ;
HWND hwndPreview = GetDlgItem( hwndDlg, IDC_COLOR1 + idx) ;
if ( ! hwndPreview)
return TRUE ;
// apertura ChooseColor (usa hwndDlg come owner)
CHOOSECOLOR cc = {} ;
cc.lStructSize = sizeof( cc) ;
cc.hwndOwner = hwndDlg ;
cc.lpCustColors = s_CustomColors ;
cc.rgbResult = selectedColor[idx] ;
cc.Flags = CC_FULLOPEN | CC_RGBINIT ;
if ( ChooseColor( &cc)) {
selectedColor[idx] = cc.rgbResult ;
// salvo nel file Ini i nuovi colori personalizzati
string sIniFile = ExeGetIniFile() ;
if ( ! sIniFile.empty()) {
string sOut = "" ;
for ( int j = 0 ; j < ssize( s_CustomColors) && j < 16 ; ++ j)
sOut += ToString( ( unsigned int)s_CustomColors[j]) + "," ;
sOut.pop_back() ;
WritePrivateProfileStringUtf8( SEC_SCENE, KEY_CUSTOMCOLORS, sOut.c_str(), sIniFile.c_str()) ;
}
if ( hColorBrush[idx] != NULL)
DeleteObject( hColorBrush[idx]) ;
hColorBrush[idx] = CreateSolidBrush( selectedColor[idx]) ;
InvalidateRect( hwndPreview, NULL, TRUE) ;
UpdateWindow( hwndPreview) ;
}
return TRUE ; // !<-- Esco
}
switch ( LOWORD( wParam)) {
case IDOK :
{
// recupero il contesto impostato alla creazione della finestra (durante esecuzione WM_INITDIALOG)
DialogContext* pdcCtx = (DialogContext*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA) ;
if ( pdcCtx != nullptr) {
// inizializzo i risultati
pdcCtx->vsResult.clear() ;
pdcCtx->vsResult.reserve( s_nCtrls) ;
// recupero i valori degli Item
for ( int i = 0 ; i < s_nCtrls ; ++ i) {
AtoWEX<128> wsEdit( "") ;
s_sEdit[i] = "" ;
switch ( s_nType[i]) {
case CTRL_CHECK :
s_sEdit[i] = ( IsDlgButtonChecked( hwndDlg, IDC_CHECK1 + i) == BST_CHECKED ? "1" : "0") ;
break ;
case CTRL_COMBO :
if ( GetDlgItemText( hwndDlg, IDC_COMBO1 + i, LPWSTR( wsEdit), 128) > 0)
s_sEdit[i] = wstrztoA( wsEdit) ;
break ;
case CTRL_EDIT :
if ( GetDlgItemText( hwndDlg, IDC_EDIT1 + i, LPWSTR( wsEdit), 128) > 0)
s_sEdit[i] = wstrztoA( wsEdit) ;
break ;
case CTRL_COLOR :
{
COLORREF col = selectedColor[i] ;
BYTE r = GetRValue( col), g = GetGValue( col), b = GetBValue( col) ;
char buf[16] ;
sprintf_s( buf, sizeof( buf), "%u,%u,%u", r, g, b) ;
s_sEdit[i] = buf ;
}
break ;
case CTRL_BUTTON :
if ( GetDlgItemText( hwndDlg, IDC_EDIT1 + i, LPWSTR( wsEdit), 128) > 0)
s_sEdit[i] = wstrztoA( wsEdit) ;
break ;
}
// inserisco i valori all'interno della tabella Lua
pdcCtx->vsResult.push_back( s_sEdit[i]) ;
}
pdcCtx->bCancelled = false ;
pdcCtx->bDone = true ;
}
// chiudo il dialogo
OnClosingDialog( hwndDlg) ;
return TRUE ;
}
[[fallthrough]] ;
case IDCANCEL :
{
// pulizia brush colori
for ( int i = 0 ; i < MAX_CTRLS ; ++ i) {
if ( hColorBrush[i] != NULL) {
DeleteObject( hColorBrush[i]) ;
hColorBrush[i] = NULL ;
}
}
// recupero il contesto impostato alla creazione della finestra ( durante esecuzione WM_INITDIALOG) e se esiste lo rimuovo
DialogContext* pdcCtx = ( DialogContext*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA) ;
if ( pdcCtx != nullptr) {
pdcCtx->bCancelled = true ;
pdcCtx->bDone = true ;
}
// chiudo il dialogo
OnClosingDialog( hwndDlg) ;
return TRUE ;
}
}
// se siamo in modalità di Selezione e il comando attivo non si riferisce ad un button di Selezione (SB), il dialogo torna modale
if ( s_bSelectionMode) {
bool bIsBS = ( id >= IDC_BUTTON_SEL1 && id < IDC_BUTTON_SEL1 + MAX_CTRLS) ;
bool bIsActiveEdit = ( id == IDC_EDIT1 + s_nActiveRow) ;
// il dialogo torna modale
if ( ! bIsBS && ! bIsActiveEdit)
EndSelectionMode( hwndDlg) ;
}
break ;
}
case WM_CLOSE :
{
// recupero il contesto impostato alla creazione della finestra ( durante esecuzione WM_INITDIALOG) e se esiste lo rimuovo
DialogContext* pdcCtx = (DialogContext*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA) ;
if ( pdcCtx != nullptr) {
pdcCtx->bCancelled = true ;
pdcCtx->bDone = true ;
}
// chiudo il dialogo
OnClosingDialog( hwndDlg) ;
return TRUE ;
}
}
return FALSE ;
}
//-----------------------------------------------------------------------------
bool
UpdateDialogIds( void)
{
// verifico presenza dialogo e item di selezione
if ( s_hDlg == NULL || s_nDlgItem == -1)
return false ;
// recupero tutti gli elementi selezionati
string sIds ;
int nId = ExeGetFirstSelectedObj() ;
while ( nId != GDB_ID_NULL) {
sIds.append( ToString( nId) + ",") ;
nId = ExeGetNextSelectedObj() ;
}
if ( ! sIds.empty())
sIds.pop_back() ;
// aggiorno il contenuto nel dialogo
return ( SetDlgItemText( s_hDlg, s_nDlgItem, stringtoW( sIds))) ;
}
//-------------------------------------------------------------------------------
// LuaDialogBox (Modeless)
//
// Scopo:
// ------
// Questa funzione implementa un dialogo "modale" dal punto di vista del codice Lua, ma "modeless" dal punto di vista della
// UI Windows quando necessario. Lobiettivo è permettere al codice Lua di rimanere sospeso finché lutente non chiude il
// dialogo (OK/Cancel/X), mantenendo però la UI attiva e permettendo selezioni nella scena quando lutente preme un pulsante
// SB (Select Button).
//
// Perché serve:
// -------------
// - I dialoghi modali standard (DialogBox) bloccano completamente la UI, mentre i dialoghi modeless standard (CreateDialog)
// NON bloccano il codice Lua.
// - Le coroutine Lua (lua_yield/lua_resume) non sono utilizzabili in questo contesto perché il thread principale
// dellapplicazione non può essere sospeso tramite yield: il codice Lua non riprende correttamente e la UI non si
// aggiorna coerentemente)
//
// Come funziona:
// --------------
// 1) Il dialogo viene creato con CreateDialogParam(), quindi la UI rimane attiva.
// 2) La funzione NON ritorna subito: entra in un message loop locale (Esattamente equivalente al loop all'interno di
// DialogBox()). Il cuore del loop è GetMessage(), che è una chiamata BLOCCANTE. Significa che il thread rimane in
// attesa senza consumare CPU finché non arriva un messaggio. Non c’è polling, non c’è busy loop. Il comportamento è
// identico a quello di un dialogo modale nativo.
// 3) Il ciclo rimane attivo finché:
// - lutente non chiude il dialogo (OK/Cancel/X)
// - oppure la finestra viene distrutta
// In quel momento ctx->bDone viene impostato a true.
// 4) Durante la vita del dialogo, se lutente preme un pulsante SB, il dialogo diventa temporaneamente "modeless":
// - la main window viene abilitata
// - il dialogo rimane abilitato ma passa in secondo piano logico
// - lutente può selezionare oggetti nella scena
// Quando la selezione termina, il dialogo torna modale.
// 5) Quando il dialogo chiude, i valori vengono copiati in ctx->vsResult e ritornati a Lua come risultato della funzione.
//
// Vantaggi della soluzione:
// -------------------------
// - Lua rimane bloccato come con un dialogo modale tradizionale.
// - La UI rimane completamente attiva.
// - Le selezioni SB (mediante Select Button) funzionano senza bloccare il programma.
// - Nessun uso di coroutine Lua (che non erano affidabili in questo contesto).
// - Nessun consumo CPU anomalo.
// - Comportamento stabile e prevedibile.
//
// Nota importante:
// ----------------
// Il dialogo NON viene mai disabilitato durante la selezione SB (Select Button). Solo la main window viene
// abilitata temporaneamente.
// Questo è fondamentale: disabilitare il dialogo impedirebbe allutente di poterlo riselezionare dopo la selezione nella scena.
//
//-------------------------------------------------------------------------------
int
LuaDialogBox( lua_State* L)
{
// 1 .. 9 parametri : sCaption, { sText, sDefault}, ...
LuaCheckParam( L, 1, s_sCaption)
s_nCtrls = 0 ;
for ( int i = 0 ; i < MAX_CTRLS ; ++ i) {
STRVECTOR vData ;
if ( LuaGetParam( L, 2 + i, vData) && ssize( vData) >= 2) {
s_sText[i] = Trim( vData[0]) ;
s_sEdit[i] = Trim( vData[1]) ;
++ s_nCtrls ;
}
else
break ;
}
LuaClearStack( L) ;
// se UI disabilitata, esco
if ( ! ExeGetEnableUI()) {
LuaSetParam( L) ;
return 1 ;
}
// se dialogo già aperto, errore
if ( s_hDlg != NULL) {
LuaSetParam( L) ;
return 1 ;
}
// definizione del contesto
DialogContext dcCtx ;
// creazione di un dialogo Modeless
HWND hMainWnd = ExeGetMainWindowHandle() ;
s_nDlgItem = -1 ;
s_hDlg = ( CreateDialogParam( GetModuleIstance(), MAKEINTRESOURCE( IDD_LUADLG), hMainWnd,
(DLGPROC)DialogBoxProc, (LPARAM) &dcCtx)) ;
if ( s_hDlg == NULL) {
LuaSetParam( L) ;
return 1 ;
}
// porto la finestra in primo piano
ShowWindow( s_hDlg, SW_SHOW) ;
SetForegroundWindow( s_hDlg) ;
// contesto corrente
RECT rctWnd{ 0, 0, 0, 0} ;
GseContext* pGseCtx = GetCurrGseContext() ;
if ( pGseCtx != nullptr)
GetWindowRect( pGseCtx->m_hWnd, &rctWnd) ;
// message Loop
MSG msg ;
while ( ! dcCtx.bDone && IsWindow( s_hDlg)) {
if ( GetMessage( &msg, NULL, 0, 0) <= 0)
break ;
if ( ! IsDialogMessage( s_hDlg, &msg) &&
( ! s_bSelectionMode || PtInRect( &rctWnd, msg.pt) != FALSE)) {
TranslateMessage( &msg) ;
DispatchMessage( &msg) ;
}
}
// ritorno i valori lua
if ( dcCtx.bCancelled)
LuaSetParam( L) ;
else
LuaSetParam( L, dcCtx.vsResult) ;
return 1 ;
}
+24
View File
@@ -0,0 +1,24 @@
//----------------------------------------------------------------------------
// EgalTech 2026-2026
//----------------------------------------------------------------------------
// File : LUA_GenDialog.h Data : 06.07.2026 Versione : 3.1g2
// Contenuto : Prototipi funzioni LUA_GenDialog.
//
//
//
// Modifiche : 06.07.26 RE Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "stdafx.h"
#include "/EgtDev/Include/EGkLuaAux.h"
//----------------------------------------------------------------------------
// Funzione implementazione DialogBox per lua
int LuaDialogBox( lua_State* L) ;
// Funzione per passaggi di parametri tra Selezione DB e dialogo non modale
bool UpdateDialogIds( void) ;
+2 -700
View File
@@ -16,9 +16,7 @@
#include "DllMain.h"
#include "EXE.h"
#include "LUA.h"
#include "GenTools.h"
#include "resource.h"
#include "AuxDialogBox.h"
#include "LUA_GenDialog.h"
#include "/EgtDev/Include/ExeExecutor.h"
#include "/EgtDev/Include/EGkLuaAux.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
@@ -31,8 +29,6 @@
#include "/EgtDev/Include/EgtIniFile.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EgtStringConverter.h"
#include <sstream>
#include <Windowsx.h>
#include <shlobj.h>
using namespace std ;
@@ -1228,705 +1224,11 @@ LuaReleaseMutex( lua_State* L)
return 1 ;
}
//-------------------------------------------------------------------------------
// =================================== DIALOG ===================================
// Variabili Globali
const int OFFS_CTRLS = 40 ;
enum TYPE_CTRLS { CTRL_NONE = 0, CTRL_CHECK = 1, CTRL_COMBO = 2, CTRL_EDIT = 3, CTRL_COLOR = 4, CTRL_BUTTON = 5} ;
static COLORREF s_CustomColors[16] = {12632256} ; // 16 colori GRAY
static bool s_bCustomColorsInit = false ; // flag di inizializzazione colori
const char* SEC_SCENE = "Scene" ;
const char* KEY_CUSTOMCOLORS = "CustomColors" ;
// Dialogo Modeless
const int MAX_CTRLS = IDC_TEXT8 - IDC_TEXT1 + 1 ;
static int s_nCtrls = 0 ;
static string s_sCaption ;
static string s_sText[MAX_CTRLS] ;
static string s_sEdit[MAX_CTRLS] ;
static int s_nType[MAX_CTRLS] ;
struct DialogContext {
bool bDone = false ; // flag per chiusura dialogo (X/Ok/Cancel)
bool bCancelled = false ; // true se X/Cancel
bool bSelecting = false ; // true quando un BS + in modalità selezione
int nLastBS = -1 ; // indice dell'ultimo BS premuto
STRVECTOR vsResult ; // valori finali da ritornare a Lua
} ;
static string s_sIdSel_ML ;
static bool s_bSelectionMode = false ; // se true allora diventa dialogo "Modeless"
static int s_nActiveRow = - 1 ; // indice della riga di "BS:" attiva
//-------------------------------------------------------------------------------
// OnClosingDialog
//
// Scopo:
// Gestisce la chiusura del dialogo modeless in modo centralizzato e sicuro.
// Questa funzione viene chiamata quando lutente chiude il dialogo tramite:
// - OK
// - Cancel
// - pulsante X
// - WM_CLOSE
//
// Comportamento:
// - Riabilita la finestra principale (Main Window), che era stata disabilitata durante il funzionamento
// modale del dialogo.
//
// - Distrugge la finestra del dialogo.
//
// - Riporta il focus alla finestra principale, garantendo continuità nellinterazione dellutente.
//
// - Deseleziona tutti gli oggetti nella scena e aggiorna la vista, in modo che nessuna selezione residua
// rimanga attiva dopo la chiusura.
//-------------------------------------------------------------------------------
static void
OnClosingDialog( HWND hwndDlg) {
// reset stato globale
s_bSelectionMode = false ;
s_nActiveRow = -1 ;
nDlgModelessItem = -1 ;
// il controllo passa al Main
HWND hMain = GetParent( hwndDlg) ;
EnableWindow( hMain, TRUE) ;
DestroyWindow( hwndDlg) ;
phDlgModeless = nullptr ;
SetFocus( hMain) ;
// deseleziono tutto
ExeDeselectAll() ;
ExeDraw() ;
}
//-------------------------------------------------------------------------------
// StartSelectionMode
//
// Scopo:
// Attiva la modalità di selezione (modeless) del dialogo. Questa modalità permette allutente di interagire
// con la scena mentre il dialogo rimane aperto e attivo.
//
// Parametri:
// hDlg → handle del dialogo
// nEditId → ID delledit associato al pulsante BS premuto
// nActiveRow → indice della riga BS attiva (0..MAX_CTRLS-1)
//-------------------------------------------------------------------------------
static void
StartSelectionMode( HWND hDlg, int nEditId, int nActiveRow)
{
// il dialogo torna modeless rispetto alla scena
HWND hMain = GetParent( hDlg) ;
EnableWindow( hMain, TRUE) ;
// resta comunque in primo piano
SetWindowPos( hDlg, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) ;
// disabilito tutti gli edit associati ai BS tranne che quello attivo
for ( int i = 0; i < s_nCtrls ; ++ i) {
if (s_sEdit[i].find( "BS:") == 0) {
int idEdit = IDC_EDIT1 + i ;
EnableWindow( GetDlgItem( hDlg, idEdit), ( i == nActiveRow ? TRUE : FALSE)) ;
}
}
// seleziono solo gli elementi presenti nell'edit corrispondente
nDlgModelessItem = - 1 ; // !<-- Temporaneo [***]
ExeDeselectAll() ; // !<-- NB. avendo messo nDlgModelessItem = -1 il testo non viene rimosso
s_bSelectionMode = true ;
s_nActiveRow = nActiveRow ;
nDlgModelessItem = nEditId ; // !<-- Aggiorno [***]
AtoWEX<128> wsEdit( "") ;
GetDlgItemText( hDlg, nEditId, LPWSTR( wsEdit), 128) ;
string sIds = wstrztoA( wsEdit) ;
STRVECTOR vsIds ;
Tokenize( sIds, ",", vsIds) ;
for ( const string& sId : vsIds) {
int nId = GDB_ID_NULL ;
if ( FromString( sId, nId) && nId != GDB_ID_NULL)
ExeSelectObj( nId) ;
}
ExeDraw() ;
}
//-------------------------------------------------------------------------------
// EndSelectionMode
//
// Scopo:
// Termina la modalità di selezione e riporta il dialogo in stato modale.
//-------------------------------------------------------------------------------
static void
EndSelectionMode( HWND hDlg)
{
s_bSelectionMode = false ;
s_nActiveRow = -1 ;
nDlgModelessItem = -1 ;
// disabilito tutti gli edit associati ai BS
for ( int i = 0; i < s_nCtrls ; ++ i) {
if ( s_sEdit[i].find( "BS:") == 0) {
int idEdit = IDC_EDIT1 + i ;
EnableWindow( GetDlgItem( hDlg, idEdit), FALSE) ;
SetDlgItemText( hDlg, IDC_BUTTON_SEL1 + i, stringtoW( string{ "-"})) ;
}
}
// il dialogo torna modale
HWND hMain = GetParent( hDlg) ;
EnableWindow( hMain, FALSE) ;
SetFocus( hDlg) ;
// deseleziono tutto
ExeDeselectAll() ; //!<-- NB. avendo messo nDlgModelessItem = -1 il testo non viene rimosso
ExeDraw() ;
}
//-------------------------------------------------------------------------------
BOOL
CALLBACK DialogBoxModelessProc( HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
// variabili static locali per mantenere lo stato tra chiamate per selezione colori
static COLORREF selectedColor[MAX_CTRLS] = {0} ; // BLACK
static HBRUSH hColorBrush[MAX_CTRLS] = {NULL} ; // non definito
switch ( message) {
case WM_INITDIALOG :
{
// imposto il dialogo come modale
HWND hMain = GetParent( hwndDlg) ;
EnableWindow( hMain, FALSE) ;
SetFocus( hwndDlg) ;
// imposto il contesto della funzione per recuperalo in futuro (per la funzione di CallBack Lua)
SetWindowLongPtr( hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam) ;
// colore di default
COLORREF defaultColor = RGB( 255, 0, 0) ;
// inizializzazione colori e brush
for ( int i = 0 ; i < MAX_CTRLS ; ++ i) {
selectedColor[i] = defaultColor ;
if ( hColorBrush[i] != NULL)
DeleteObject( hColorBrush[i]) ;
hColorBrush[i] = CreateSolidBrush( selectedColor[i]) ;
}
// dati del dialogo
HWND hwndOwner = GetParent( hwndDlg) ;
if ( hwndOwner == nullptr)
hwndOwner = GetDesktopWindow() ;
RECT rcOwner, rcDlg ;
GetWindowRect( hwndOwner, &rcOwner) ;
GetWindowRect( hwndDlg, &rcDlg) ;
// determino la posizione dell'ultima riga di dati da visualizzare
HWND hwndLR = GetDlgItem( hwndDlg, IDC_TEXT1 + Clamp( s_nCtrls, 1, MAX_CTRLS) - 1) ;
RECT rcLR ;
GetWindowRect( hwndLR, &rcLR) ;
POINT ptLR{ rcLR.left, rcLR.top} ;
ScreenToClient( hwndDlg, &ptLR) ;
// centro e scalo il dialogo
int nNewH = rcLR.top - rcOwner.top + 2 * OFFS_CTRLS ; // non chiaro perchè va sottratto rcOwner.top ma funziona sempre
SetWindowPos( hwndDlg, HWND_TOP,
( rcOwner.left + rcOwner.right - ( rcDlg.right - rcDlg.left)) / 2,
( rcOwner.top + rcOwner.bottom - nNewH) / 2,
( rcDlg.right - rcDlg.left),
nNewH, 0) ;
// riposiziono il bottone Ok
HWND hwndOk = GetDlgItem( hwndDlg, IDOK) ;
RECT rcOk ;
GetWindowRect( hwndOk, &rcOk) ;
POINT ptOk{ rcOk.left, rcOk.top} ;
ScreenToClient( hwndDlg, &ptOk) ;
SetWindowPos( hwndOk, hwndDlg, ptOk.x, ptLR.y + OFFS_CTRLS, 0, 0, SWP_NOSIZE | SWP_NOZORDER) ;
// riposiziono il bottone Cancel
HWND hwndCl = GetDlgItem( hwndDlg, IDCANCEL) ;
RECT rcCl ;
GetWindowRect( hwndCl, &rcCl) ;
POINT ptCl{ rcCl.left, rcCl.top} ;
ScreenToClient( hwndDlg, &ptCl) ;
SetWindowPos( hwndCl, hwndDlg, ptCl.x, ptLR.y + OFFS_CTRLS, 0, 0, SWP_NOSIZE | SWP_NOZORDER) ;
// stile finestra
LONG style = GetWindowLong( hwndDlg, GWL_STYLE) ;
style |= WS_SYSMENU ;
SetWindowLong( hwndDlg, GWL_STYLE, style) ;
}
// assegno titolo del dialogo
SetWindowText( hwndDlg, stringtoW( s_sCaption)) ;
// assegno testi e valori di default e nascondo linee dei controlli non usati
for ( int i = 0 ; i < MAX_CTRLS ; ++ i) {
if ( i < s_nCtrls) {
// imposto il testo nella riga corrente
SetDlgItemText( hwndDlg, IDC_TEXT1 + i, stringtoW( s_sText[i])) ;
// --- se CheckBox
if ( s_sEdit[i].find( "CK:") == 0) {
bool bChecked = false ;
FromString( s_sEdit[i].substr( 3), bChecked) ;
CheckDlgButton( hwndDlg, IDC_CHECK1 + i, ( bChecked ? BST_CHECKED : BST_UNCHECKED)) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_EDIT1 + i), SW_HIDE) ; // nascondo Edit
ShowWindow( GetDlgItem( hwndDlg, IDC_COMBO1 + i), SW_HIDE) ; // nascondo Combo
ShowWindow( GetDlgItem( hwndDlg, IDC_BUTTON_SEL1 + i), SW_HIDE) ; // nascondo Button di selezione
s_nType[i] = CTRL_CHECK ;
}
// --- se ComboBox
else if ( s_sEdit[i].find( "CB:") == 0) {
string sList = s_sEdit[i].substr( 3) ;
STRVECTOR vsVal ;
Tokenize( sList, ",", vsVal) ;
int nSel = 0 ;
HWND hwndCBox = GetDlgItem( hwndDlg, IDC_COMBO1 + i) ;
for ( int j = 0 ; j < ssize( vsVal) ; ++ j) {
string sItem ;
if ( vsVal[j][0] == '*') {
nSel = j ;
sItem = vsVal[j].substr( 1) ;
}
else
sItem = vsVal[j] ;
ComboBox_AddString( hwndCBox, stringtoW( sItem)) ;
}
ComboBox_SetCurSel( hwndCBox, nSel) ;
int nEditHeight = int( SendMessage( hwndCBox, CB_GETITEMHEIGHT, (WPARAM)-1, 0)) ;
int nItemHeight = int( SendMessage( hwndCBox, CB_GETITEMHEIGHT, 0, 0)) ;
int nTotalHeight = nEditHeight + nItemHeight * ( ssize( vsVal) + 1) ;
RECT rc ; GetWindowRect( hwndCBox, &rc) ;
HWND parent = GetParent(hwndCBox) ; MapWindowPoints( NULL, parent, (LPPOINT)&rc, 2) ;
SetWindowPos( hwndCBox, NULL, rc.left, rc.top, rc.right - rc.left, nTotalHeight, SWP_NOZORDER) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_EDIT1 + i), SW_HIDE) ; // nascondo Edit
ShowWindow( GetDlgItem( hwndDlg, IDC_CHECK1 + i), SW_HIDE) ; // nascondo CheckBox
ShowWindow( GetDlgItem( hwndDlg, IDC_BUTTON_SEL1 + i), SW_HIDE) ; // nascondo Button di selezione
s_nType[i] = CTRL_COMBO ;
}
// --- se ColorPicker
else if ( s_sEdit[i].find( "CP:") == 0) {
string sVal = s_sEdit[i].substr( 3) ;
Color CColor ;
if ( ! FromString( sVal, CColor))
CColor = INVISIBLE ;
selectedColor[i] = RGB( CColor.GetIntRed(), CColor.GetIntGreen(), CColor.GetIntBlue()) ;
if ( hColorBrush[i] != NULL)
DeleteObject( hColorBrush[i]) ;
hColorBrush[i] = CreateSolidBrush( selectedColor[i]) ;
// recupero i valori dei colori personalizzati dal file .ini
if ( ! s_bCustomColorsInit) {
// recupero il file Ini
string sIniFile = ExeGetIniFile() ;
if ( ! sIniFile.empty()) {
string sCustomVals = GetPrivateProfileStringUtf8( SEC_SCENE, KEY_CUSTOMCOLORS, "", sIniFile.c_str()) ;
STRVECTOR vsWinColors ; Tokenize( sCustomVals, ",", vsWinColors) ;
for ( int j = 0 ; j < ssize( vsWinColors) && j < 16 ; ++ j) {
unsigned int unVal ;
if ( FromString( vsWinColors[j], unVal)) {
unsigned int unR = unVal & 0xFF ;
unsigned int unG = ( unVal >> 8) & 0xFF ;
unsigned int unB = ( unVal >> 16) & 0xFF ;
s_CustomColors[j] = RGB( unR, unG, unB) ;
}
}
}
s_bCustomColorsInit = true ;
}
// nascondo qualsiasi tipo di componente
ShowWindow( GetDlgItem( hwndDlg, IDC_EDIT1 + i), SW_HIDE) ; // nascondo Edit
ShowWindow( GetDlgItem( hwndDlg, IDC_COMBO1 + i), SW_HIDE) ; // nascondo Combo
ShowWindow( GetDlgItem( hwndDlg, IDC_CHECK1 + i), SW_HIDE) ; // nascondo Check
ShowWindow( GetDlgItem( hwndDlg, IDC_BUTTON_SEL1 + i), SW_HIDE) ; // nascondo Button di selezione
// margini per dimensione del rettangolo preview pickColor
const int MARGIN_RIGHT = 8 ; // spazio tra preview e bordo destro dialog
const int PREVIEW_HEIGHT = 20 ; // altezza del rettangolo
const int PREVIEW_MIN_WIDTH = 40 ; // larghezza minima
// creazione della static preview
HWND hwndPreview = NULL ;
HWND hwndEdit = GetDlgItem( hwndDlg, IDC_EDIT1 + i) ;
RECT rcEdit ; GetClientRect( hwndDlg, &rcEdit) ; // coordinate client del dialog
if ( hwndEdit != nullptr && GetWindowRect( hwndEdit, &rcEdit)) {
// converti rcLabel in coordinate client
POINT ptEdit = { rcEdit.left, rcEdit.top } ;
ScreenToClient( hwndDlg, &ptEdit) ;
int x = ptEdit.x ;
int y = ptEdit.y ;
int width = rcEdit.right - rcEdit.left ;
if ( width < PREVIEW_MIN_WIDTH)
width = PREVIEW_MIN_WIDTH ;
hwndPreview = CreateWindowEx( 0, L"STATIC", NULL,
WS_CHILD | WS_VISIBLE | SS_NOTIFY | SS_CENTERIMAGE | WS_BORDER,
x, y, width, PREVIEW_HEIGHT,
hwndDlg, ( HMENU)( IDC_COLOR1 + i),
GetModuleHandle( NULL), NULL) ;
}
// pulizia elementi testuali
if ( hwndPreview) {
SetWindowText( hwndPreview, L"") ;
SetWindowPos( hwndPreview, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) ;
InvalidateRect( hwndPreview, NULL, TRUE) ;
UpdateWindow( hwndPreview) ;
}
s_nType[i] = CTRL_COLOR ;
}
// --- se Button di selezione
else if ( s_sEdit[i].find( "BS:") == 0) {
ShowWindow( GetDlgItem( hwndDlg, IDC_COMBO1 + i), SW_HIDE) ; // nascondo la Combo
ShowWindow( GetDlgItem( hwndDlg, IDC_CHECK1 + i), SW_HIDE) ; // nascondo la Check
SetDlgItemText( hwndDlg, IDC_BUTTON_SEL1 + i, stringtoW( string{ "-"})) ; // modalità non Selezione
EnableWindow( GetDlgItem( hwndDlg, IDC_EDIT1 + i), FALSE) ; // disattivo la Edit
// associo alla casella di testo la funzione di KeyPress su Enter
HWND hEdit = GetDlgItem( hwndDlg, IDC_EDIT1 + i) ;
if ( hEdit != nullptr)
SetWindowSubclass( hEdit, UpdateSelectionModelessDialog, 1, (DWORD_PTR)( IDC_EDIT1 + i)) ;
s_nType[i] = CTRL_BUTTON ;
}
// --- se Testo
else {
SetDlgItemText( hwndDlg, IDC_EDIT1 + i, stringtoW( s_sEdit[i])) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_COMBO1 + i), SW_HIDE) ; // nascondo Combo
ShowWindow( GetDlgItem( hwndDlg, IDC_CHECK1 + i), SW_HIDE) ; // nascondo Check
ShowWindow( GetDlgItem( hwndDlg, IDC_BUTTON_SEL1 + i), SW_HIDE) ; // nascondo Button di selezione
s_nType[i] = CTRL_EDIT ;
}
}
// se numero di controllo superiore al massimo, non visualizzo nullo ( in questo caso aggiungere elementi a Dialog in .rc)
else {
// nascondo tutto
ShowWindow( GetDlgItem( hwndDlg, IDC_TEXT1 + i), SW_HIDE) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_EDIT1 + i), SW_HIDE) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_COMBO1 + i), SW_HIDE) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_CHECK1 + i), SW_HIDE) ;
ShowWindow( GetDlgItem( hwndDlg, IDC_BUTTON_SEL1 + i), SW_HIDE) ;
s_nType[i] = CTRL_NONE ;
}
}
break ;
case WM_CTLCOLORSTATIC :
{
HDC hdcStatic = ( HDC)wParam ;
HWND hwndCtrl = ( HWND)lParam ;
int ctrlId = GetDlgCtrlID( hwndCtrl) ;
if ( ctrlId >= IDC_COLOR1 && ctrlId <= IDC_COLOR8) {
int idx = ctrlId - IDC_COLOR1 ;
if ( hColorBrush[idx] == NULL)
hColorBrush[idx] = CreateSolidBrush( selectedColor[idx]) ;
SetBkMode( hdcStatic, OPAQUE) ;
SetBkColor( hdcStatic, selectedColor[idx]) ;
return ( INT_PTR)hColorBrush[idx] ;
}
}
break ;
case WM_COMMAND : {
int id = LOWORD( wParam) ;
int code = HIWORD( wParam) ;
// --- se click di un Button di selezione
if ( id >= IDC_BUTTON_SEL1 && id < IDC_BUTTON_SEL1 + MAX_CTRLS) {
int nBtnId = id ;
int nEditId = IDC_EDIT1 + ( id - IDC_BUTTON_SEL1) ;
int nActiveRow = nEditId - IDC_EDIT1 ;
// se il bottone premuto è lo stesso
if ( nDlgModelessItem == nEditId) {
// se selezione attiva, allora deve terminare
if ( s_bSelectionMode) {
SetDlgItemText( hwndDlg, nBtnId, stringtoW( string{ "-"})) ;
EndSelectionMode( hwndDlg) ;
}
// se selezione non attiva, allora viene attivata
else {
SetDlgItemText( hwndDlg, nBtnId, stringtoW( string{ "S"})) ;
StartSelectionMode( hwndDlg, nEditId, nActiveRow) ;
}
}
// se nuovo buttone premuto
else {
// se esisteva una selezione precedente, questa viene annullata
if ( nDlgModelessItem != -1) {
// recupero il Button di selezione precedente e modifico il suo testo
int nPrevBtnId = IDC_BUTTON_SEL1 + ( nDlgModelessItem - IDC_EDIT1) ;
SetDlgItemText( hwndDlg, nPrevBtnId, stringtoW( string{ "-"})) ;
}
// la selezione passa al comando corrente
nDlgModelessItem = nEditId ;
SetDlgItemText( hwndDlg, nBtnId, stringtoW( string{ "S"})) ;
// il dialogo diventa "Modeless" temporaneamente
s_nActiveRow = nEditId - IDC_EDIT1 ;
StartSelectionMode( hwndDlg, nEditId, nActiveRow) ;
}
return TRUE ; // !<-- esco
}
// --- se comando di Preview per brush di colori mediante click del mouse
else if ( code == STN_CLICKED && id >= IDC_COLOR1 && id <= IDC_COLOR8) {
// se selezione attiva, allora deve terminare
if ( s_bSelectionMode) {
// se esisteva una selezione precedente, questa viene annullata
if ( nDlgModelessItem != -1) {
// recupero il Button di selezione precedente e modifico il suo testo
int nPrevBtnId = IDC_BUTTON_SEL1 + ( nDlgModelessItem - IDC_EDIT1) ;
SetDlgItemText( hwndDlg, nPrevBtnId, stringtoW( string{ "-"})) ;
}
EndSelectionMode( hwndDlg) ;
}
int idx = id - IDC_COLOR1 ;
HWND hwndPreview = GetDlgItem( hwndDlg, IDC_COLOR1 + idx) ;
if ( ! hwndPreview)
return TRUE ;
// apertura ChooseColor (usa hwndDlg come owner)
CHOOSECOLOR cc = {} ;
cc.lStructSize = sizeof( cc) ;
cc.hwndOwner = hwndDlg ;
cc.lpCustColors = s_CustomColors ;
cc.rgbResult = selectedColor[idx] ;
cc.Flags = CC_FULLOPEN | CC_RGBINIT ;
if ( ChooseColor( &cc)) {
selectedColor[idx] = cc.rgbResult ;
// salvo nel file Ini i nuovi colori personalizzati
string sIniFile = ExeGetIniFile() ;
if ( ! sIniFile.empty()) {
string sOut = "" ;
for ( int j = 0 ; j < ssize( s_CustomColors) && j < 16 ; ++ j)
sOut += ToString( ( unsigned int)s_CustomColors[j]) + "," ;
sOut.pop_back() ;
WritePrivateProfileStringUtf8( SEC_SCENE, KEY_CUSTOMCOLORS, sOut.c_str(), sIniFile.c_str()) ;
}
if ( hColorBrush[idx] != NULL)
DeleteObject( hColorBrush[idx]) ;
hColorBrush[idx] = CreateSolidBrush( selectedColor[idx]) ;
InvalidateRect(hwndPreview, NULL, TRUE) ;
UpdateWindow( hwndPreview) ;
}
return TRUE ; // !<-- Esco
}
switch ( LOWORD( wParam)) {
case IDOK : {
// recupero il contesto impostato alla creazione della finestra (durante esecuzione WM_INITDIALOG)
DialogContext* ctx = (DialogContext*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA) ;
if ( ctx != nullptr) {
// inizializzo i risultati
ctx->vsResult.clear() ;
ctx->vsResult.reserve( s_nCtrls) ;
// recupero i valori degli Item
for ( int i = 0 ; i < s_nCtrls ; ++ i) {
AtoWEX<128> wsEdit( "") ;
s_sEdit[i] = "" ;
switch ( s_nType[i]) {
case CTRL_CHECK :
s_sEdit[i] = ( IsDlgButtonChecked( hwndDlg, IDC_CHECK1 + i) == BST_CHECKED ? "1" : "0") ;
break ;
case CTRL_COMBO :
if ( GetDlgItemText( hwndDlg, IDC_COMBO1 + i, LPWSTR( wsEdit), 128) > 0)
s_sEdit[i] = wstrztoA( wsEdit) ;
break ;
case CTRL_EDIT :
if ( GetDlgItemText( hwndDlg, IDC_EDIT1 + i, LPWSTR( wsEdit), 128) > 0)
s_sEdit[i] = wstrztoA( wsEdit) ;
break ;
case CTRL_COLOR :
{
COLORREF col = selectedColor[i] ;
BYTE r = GetRValue( col), g = GetGValue( col), b = GetBValue( col) ;
char buf[16] ;
sprintf_s( buf, sizeof( buf), "%u,%u,%u", r, g, b) ;
s_sEdit[i] = buf ;
}
break ;
case CTRL_BUTTON :
if ( GetDlgItemText( hwndDlg, IDC_EDIT1 + i, LPWSTR( wsEdit), 128) > 0)
s_sEdit[i] = wstrztoA( wsEdit) ;
break ;
}
// inserisco i valori all'interno della tabella Lua
ctx->vsResult.push_back( s_sEdit[i]) ;
}
ctx->bCancelled = false ;
ctx->bDone = true ;
}
// chiudo il dialogo
OnClosingDialog( hwndDlg) ;
return TRUE ;
}
[[fallthrough]] ;
case IDCANCEL : {
// pulizia brush colori
for ( int i = 0 ; i < MAX_CTRLS ; ++ i) {
if ( hColorBrush[i] != NULL) {
DeleteObject( hColorBrush[i]) ;
hColorBrush[i] = NULL ;
}
}
// recupero il contesto impostato alla creazione della finestra ( durante esecuzione WM_INITDIALOG) e se esiste lo rimuovo
DialogContext* ctx = (DialogContext*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA) ;
if ( ctx != nullptr) {
ctx->bCancelled = true ;
ctx->bDone = true ;
}
// chiudo il dialogo
OnClosingDialog( hwndDlg) ;
return TRUE ;
}
}
// se siamo in modalità di Selezione e il comando attivo non si riferisce ad un button di Selezione (BS), il dialogo torna modale
if ( s_bSelectionMode) {
bool bIsBS = ( id >= IDC_BUTTON_SEL1 && id < IDC_BUTTON_SEL1 + MAX_CTRLS) ;
bool bIsActiveEdit = ( id == IDC_EDIT1 + s_nActiveRow) ;
// il dialogo torna modale
if ( ! bIsBS && ! bIsActiveEdit)
EndSelectionMode( hwndDlg) ;
}
break ;
}
case WM_CLOSE : {
// recupero il contesto impostato alla creazione della finestra ( durante esecuzione WM_INITDIALOG) e se esiste lo rimuovo
DialogContext* ctx = (DialogContext*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA) ;
if ( ctx != nullptr) {
ctx->bCancelled = true ;
ctx->bDone = true ;
}
// chiudo il dialogo
OnClosingDialog( hwndDlg) ;
return TRUE ;
}
}
return FALSE ;
}
//-------------------------------------------------------------------------------
// LuaDialogBox (Modeless)
//
// Scopo:
// ------
// Questa funzione implementa un dialogo "modale" dal punto di vista del codice Lua, ma "modeless" dal punto di vista della
// UI Windows quando necessario. Lobiettivo è permettere al codice Lua di rimanere sospeso finché lutente non chiude il
// dialogo (OK/Cancel/X), mantenendo però la UI attiva e permettendo selezioni nella scena quando lutente preme un pulsante
// BS (Button Selection).
//
// Perché serve:
// -------------
// - I dialoghi modali standard (DialogBox) bloccano completamente la UI, mentre i dialoghi modeless standard (CreateDialog)
// NON bloccano il codice Lua.
// - Le coroutine Lua (lua_yield/lua_resume) non sono utilizzabili in questo contesto perché il thread principale
// dellapplicazione non può essere sospeso tramite yield: il codice Lua non riprende correttamente e la UI non si
// aggiorna coerentemente)
//
// Come funziona:
// --------------
// 1) Il dialogo viene creato con CreateDialogParam(), quindi la UI rimane attiva.
// 2) La funzione NON ritorna subito: entra in un message loop locale (Esattamente equivalente al loop all'interno di
// DialogBox()). Il cuore del loop è GetMessage(), che è una chiamata BLOCCANTE. Significa che il thread rimane in
// attesa senza consumare CPU finché non arriva un messaggio. Non c’è polling, non c’è busy loop. Il comportamento è
// identico a quello di un dialogo modale nativo.
// 3) Il ciclo rimane attivo finché:
// - lutente non chiude il dialogo (OK/Cancel/X)
// - oppure la finestra viene distrutta
// In quel momento ctx->bDone viene impostato a true.
// 4) Durante la vita del dialogo, se lutente preme un pulsante BS, il dialogo diventa temporaneamente "modeless":
// - la main window viene abilitata
// - il dialogo rimane abilitato ma passa in secondo piano logico
// - lutente può selezionare oggetti nella scena
// Quando la selezione termina, il dialogo torna modale.
// 5) Quando il dialogo chiude, i valori vengono copiati in ctx->vsResult e ritornati a Lua come risultato della funzione.
//
// Vantaggi della soluzione:
// -------------------------
// - Lua rimane bloccato come con un dialogo modale tradizionale.
// - La UI rimane completamente attiva.
// - Le selezioni BS (mediante Button Selection) funzionano senza bloccare il programma.
// - Nessun uso di coroutine Lua (che non erano affidabili in questo contesto).
// - Nessun consumo CPU anomalo.
// - Comportamento stabile e prevedibile.
//
// Nota importante:
// ----------------
// Il dialogo NON viene mai disabilitato durante la selezione BS (Button Selection). Solo la main window viene
// abilitata temporaneamente.
// Questo è fondamentale: disabilitare il dialogo impedirebbe allutente di poterlo riselezionare dopo la selezione nella scena.
//
static int
LuaDialogBox( lua_State* L)
{
// 1 .. 9 parametri : sCaption, { sText, sDefault}, ...
LuaCheckParam( L, 1, s_sCaption)
s_nCtrls = 0 ;
for ( int i = 0 ; i < MAX_CTRLS ; ++ i) {
STRVECTOR vData ;
if ( LuaGetParam( L, 2 + i, vData) && ssize( vData) >= 2) {
s_sText[i] = Trim( vData[0]) ;
s_sEdit[i] = Trim( vData[1]) ;
++ s_nCtrls ;
}
else
break ;
}
LuaClearStack( L) ;
// se UI disabilitata, esco
if ( ! ExeGetEnableUI()) {
LuaSetParam( L) ;
return 1 ;
}
// se dialogo Modeless già aperto, errore
if ( phDlgModeless != nullptr) {
LuaSetParam( L) ;
return 1 ;
}
// creazione del contesto e della Coroutine da gestire
DialogContext* ctx = new DialogContext() ;
if ( ctx == nullptr) {
LuaSetParam( L) ;
return 1 ;
}
// creazione di un dialogo Modeless
HWND hTopWnd = ExeGetMainWindowHandle() ;
nDlgModelessItem = -1 ;
phDlgModeless = ( CreateDialogParam( GetModuleIstance(), MAKEINTRESOURCE( IDD_LUADLG), hTopWnd,
(DLGPROC)DialogBoxModelessProc, (LPARAM)ctx)) ;
if ( phDlgModeless == nullptr) {
delete( ctx) ;
ctx = nullptr ;
LuaSetParam( L) ;
return 1 ;
}
// porto la finestra in primo piano
ShowWindow( phDlgModeless, SW_SHOW) ;
SetForegroundWindow( phDlgModeless) ;
// message Loop Modale (ripresa del Loop come da dialogo modale)
MSG msg ;
while ( ! ctx->bDone && IsWindow( phDlgModeless)) {
if ( GetMessage( &msg, NULL, 0, 0) <= 0)
break ;
if ( ! IsDialogMessage( phDlgModeless, &msg)) {
TranslateMessage( &msg) ;
DispatchMessage( &msg) ;
}
}
// ritorno i valori lua
if ( ctx->bCancelled)
LuaSetParam( L, false) ;
else
LuaSetParam( L, ctx->vsResult) ;
// libero la memoria
delete ctx ;
ctx = nullptr ;
return 1 ;
}
//-------------------------------------------------------------------------------
bool
LuaInstallGeneral( LuaMgr& luaMgr)
{
bool bOk = ( &luaMgr != nullptr) ;
bool bOk = true ;
bOk = bOk && luaMgr.RegisterFunction( "print", MyPrint) ;
bOk = bOk && luaMgr.RegisterFunction( "EgtEvalNumExpr", LuaEvalNumExpr) ;
bOk = bOk && luaMgr.RegisterFunction( "EgtPause", LuaPause) ;
+1
View File
@@ -35,3 +35,4 @@
#pragma comment( lib, EGTEXTDIR "hiredis/Lib/hiredis" EGTLIBVER ".lib")
#pragma comment( lib, EGTLIBDIR "SEgtLock" EGTLIBVER ".lib")
#pragma comment( lib, "ws2_32.lib")
#pragma comment( lib, "Comctl32.lib")