88 $this->countCtrls = 1000;
89 $this->callback = array();
103 public function createAppWindow($caption, $width, $height, $style =
null, $params =
null): mixed
105 return $this->
createWindow(
null, AppWindow, $caption, WBC_CENTER, WBC_CENTER, $width, $height, $style, $params);
123 public function createWindow($parent, $wclass, $caption, $xPos, $yPos, $width, $height, $style =
null, $params =
null): mixed
128 $parent = $parent ===
null ? 0 : $parent;
131 $style = $style ===
null ? 0 : $style;
132 $params = $params ===
null ? 0 : $params;
136 'Creating window: class=' . $wclass .
', caption=' . $caption .
', pos=(' . $xPos .
',' . $yPos .
'), size=(' . $width .
'x' . $height .
'), style=' . $style .
', params=' . $params
139 $caption = empty($caption) ? $this->defaultTitle : $this->defaultTitle .
' - ' . $caption;
140 $window = $this->
callWinBinder(
'wb_create_window', array($parent, $wclass, $caption, $xPos, $yPos, $width, $height, $style, $params));
142 if ($window ===
false || $window ===
null) {
143 $this->
writeLog(
'ERROR: Failed to create window - wb_create_window returned: ' . var_export($window,
true));
145 if (!extension_loaded(
'winbinder')) {
146 $this->
writeLog(
'ERROR: WinBinder extension is not loaded!');
149 if (!function_exists(
'wb_create_window')) {
150 $this->
writeLog(
'ERROR: wb_create_window function does not exist!');
153 $this->
writeLog(
'Window created successfully: handle=' . $window);
171 private function callWinBinder($function, $params = array(), $removeErrorHandler =
false): mixed
174 if (function_exists($function)) {
175 if ($removeErrorHandler) {
177 $oldErrorLevel = error_reporting(0);
178 $result = @call_user_func_array($function, $params);
179 error_reporting($oldErrorLevel);
181 $result = call_user_func_array($function, $params);
198 if ($wbobject ===
null) {
199 error_log(
'Error: $wbobject is null.');
204 if (!file_exists($path)) {
205 error_log(
'Error: Image file does not exist at path: ' . $path);
210 return $this->
callWinBinder(
'wb_set_image', array($wbobject, $path));
224 public function createNakedWindow($caption, $width, $height, $style =
null, $params =
null): mixed
226 $window = $this->
createWindow(
null, NakedWindow, $caption, WBC_CENTER, WBC_CENTER, $width, $height, $style, $params);
227 $this->
setArea($window, $width, $height);
241 public function setArea($wbobject, $width, $height): mixed
243 return $this->
callWinBinder(
'wb_set_area', array($wbobject, WBC_TITLE, 0, 0, $width, $height));
261 $windowTitle = $this->
getText($window);
272 while ($attempt < $maxAttempts && !$destroyed) {
282 $this->
exec(
'taskkill',
'/FI "WINDOWTITLE eq ' . $windowTitle .
'" /F',
true);
286 if (!empty($currentPid)) {
287 $this->
exec(
'taskkill',
'/PID ' . $currentPid .
' /T /F',
true);
288 $this->
writeLog(
'Force-killed PID: ' . $currentPid .
' for window: ' . $window);
293 $this->
callWinBinder(
'wb_destroy_window', array($window),
true);
313 return $this->
callWinBinder(
'wb_get_text', array($wbobject));
330 $text = $this->
callWinBinder(
'wb_get_text', array($window),
true);
332 return ($text !==
false);
358 public function exec($cmd, $params =
null, $silent =
false, $wait =
true, $showWindow =
false): mixed
361 if (is_array($params)) {
363 foreach ($params as $arg) {
366 $params = implode(
' ', $quotedParams);
373 $wsh =
new COM(
'WScript.Shell');
374 $fullCmd =
'"' . $cmd .
'"' . (empty($params) ?
'' :
' ' . $params);
376 $exitCode = $wsh->Run($fullCmd, 0, $wait);
377 $this->
writeLog(
'exec (silent via COM): ' . $fullCmd .
' [ExitCode: ' . $exitCode .
']');
379 return $exitCode === 0;
380 }
catch (Throwable $e) {
381 $this->
writeLog(
'exec (silent via COM) failed: ' . $e->getMessage() .
'. Falling back to PowerShell.');
383 $psCmd =
'Start-Process -FilePath \'' . str_replace(
"'",
"''", $cmd) .
'\'';
384 if (!empty($params)) {
385 $psCmd .=
' -ArgumentList \'' . str_replace(
"'",
"''", $params) .
'\'';
387 $psCmd .=
' -WindowStyle Hidden';
391 $encodedCmd = base64_encode(mb_convert_encoding($psCmd,
'UTF-16LE',
'UTF-8'));
392 $cmd =
'powershell.exe';
393 $params =
'-WindowStyle Hidden -ExecutionPolicy Bypass -EncodedCommand ' . $encodedCmd;
397 $this->
writeLog(
'exec: ' . $cmd .
' ' . $params);
400 return $this->
callWinBinder(
'wb_exec', array($cmd, $params,
true));
403 return $this->
callWinBinder(
'wb_exec', array($cmd, $params));
426 if (preg_match(
'/[\s"&|<>^()]/', $arg)) {
428 $escaped = str_replace(
'"',
'""', $arg);
430 return '"' . $escaped .
'"';
468 return $this->
callWinBinder(
'wb_refresh', array($wbobject,
true));
480 return $this->
callWinBinder(
'wb_get_system_info', array($info));
495 public function drawImage($wbobject, $path, $xPos = 0, $yPos = 0, $width = 0, $height = 0): mixed
497 $image = $this->
callWinBinder(
'wb_load_image', array($path));
498 if ($image ===
null) {
502 return $this->
callWinBinder(
'wb_draw_image', array($wbobject, $image, $xPos, $yPos, $width, $height));
518 public function drawText($parent, $caption, $xPos, $yPos, $width =
null, $height =
null, $font =
null)
521 $caption = $caption ===
null ?
'' : $caption;
522 $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption);
523 $width = $width ==
null ? 120 : $width;
524 $height = $height ==
null ? 25 : $height;
526 return $this->
callWinBinder(
'wb_draw_text', array($parent, $caption, $xPos, $yPos, $width, $height, $font));
542 public function drawRect($parent, $xPos, $yPos, $width, $height, $color = 15790320, $filled =
true)
544 return $this->
callWinBinder(
'wb_draw_rect', array($parent, $xPos, $yPos, $width, $height, $color, $filled));
560 public function drawLine($wbobject, $xStartPos, $yStartPos, $xEndPos, $yEndPos, $color, $height = 1)
562 return $this->
callWinBinder(
'wb_draw_line', array($wbobject, $xStartPos, $yStartPos, $xEndPos, $yEndPos, $color, $height));
575 public function createFont($fontName, $size =
null, $color =
null, $style =
null)
577 return $this->
callWinBinder(
'wb_create_font', array($fontName, $size, $color, $style));
587 public function wait($wbobject =
null)
589 return $this->
callWinBinder(
'wb_wait', array($wbobject),
true);
602 return $this->
callWinBinder(
'wb_destroy_timer', array($wbobject, $timerobject));
630 public function setHandler($wbobject, $classCallback, $methodCallback, $launchTimer =
null)
632 if ($launchTimer !=
null) {
633 $launchTimer = $this->
createTimer($wbobject, $launchTimer);
636 $this->callback[$wbobject] = array($classCallback, $methodCallback, $launchTimer);
638 return $this->
callWinBinder(
'wb_set_handler', array($wbobject,
'__winbinderEventHandler'));
654 self::CTRL_ID => $this->countCtrls,
655 self::CTRL_OBJ => $this->
callWinBinder(
'wb_create_timer', array($wbobject, $this->countCtrls, $wait))
670 $content = $content ===
null ?
'' : $content;
671 $content = str_replace(self::NEW_LINE, PHP_EOL, $content);
673 return $this->
callWinBinder(
'wb_set_text', array($wbobject, $content));
695 return $this->
callWinBinder(
'wb_set_focus', array($wbobject));
707 return $this->
callWinBinder(
'wb_get_enabled', array($wbobject));
732 return $this->
callWinBinder(
'wb_set_enabled', array($wbobject, $enabled));
745 return $this->
callWinBinder(
'wb_set_style', array($wbobject, $style));
759 return $this->
callWinBinder(
'wb_sys_dlg_path', array($parent, $title, $path));
772 public function sysDlgOpen($parent, $title, $filter =
null, $path =
null)
774 return $this->
callWinBinder(
'wb_sys_dlg_open', array($parent, $title, $filter, $path));
791 public function createLabel($parent, $caption, $xPos, $yPos, $width =
null, $height =
null, $style =
null, $params =
null)
793 $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption);
794 $width = $width ==
null ? 120 : $width;
795 $height = $height ==
null ? 25 : $height;
797 return $this->
createControl($parent, Label, $caption, $xPos, $yPos, $width, $height, $style, $params);
815 public function createControl($parent, $ctlClass, $caption, $xPos, $yPos, $width, $height, $style =
null, $params =
null)
820 $style = $style ===
null ? 0 : $style;
821 $params = $params ===
null ? 0 : $params;
824 self::CTRL_ID => $this->countCtrls,
825 self::CTRL_OBJ => $this->
callWinBinder(
'wb_create_control', array(
855 public function createInputText($parent, $value, $xPos, $yPos, $width =
null, $height =
null, $maxLength =
null, $style =
null, $params =
null)
858 $value = $value ===
null ?
'' : $value;
859 $value = str_replace(self::NEW_LINE, PHP_EOL, $value);
860 $width = $width ==
null ? 120 : $width;
861 $height = $height ==
null ? 25 : $height;
862 $inputText = $this->
createControl($parent, EditBox, (
string)$value, $xPos, $yPos, $width, $height, $style, $params);
863 if (is_numeric($maxLength) && $maxLength > 0) {
864 $this->
setMaxLength($inputText[self::CTRL_OBJ], $maxLength);
882 return $this->
callWinBinder(
'wb_send_message', array($wbobject, 0x00c5, $length, 0),
true);
899 public function createEditBox($parent, $value, $xPos, $yPos, $width =
null, $height =
null, $style =
null, $params =
null)
901 $value = str_replace(self::NEW_LINE, PHP_EOL, $value);
902 $width = $width ==
null ? 540 : $width;
903 $height = $height ==
null ? 340 : $height;
904 $editBox = $this->
createControl($parent, RTFEditBox, (
string)$value, $xPos, $yPos, $width, $height, $style, $params);
923 public function createHyperLink($parent, $caption, $xPos, $yPos, $width =
null, $height =
null, $style =
null, $params =
null)
925 $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption);
926 $width = $width ==
null ? 120 : $width;
927 $height = $height ==
null ? 15 : $height;
928 $hyperLink = $this->
createControl($parent, HyperLink, (
string)$caption, $xPos, $yPos, $width, $height, $style, $params);
929 $this->
setCursor($hyperLink[self::CTRL_OBJ], self::CURSOR_FINGER);
942 public function setCursor($wbobject, $type = self::CURSOR_ARROW)
944 return $this->
callWinBinder(
'wb_set_cursor', array($wbobject, $type));
961 public function createRadioButton($parent, $caption, $checked, $xPos, $yPos, $width =
null, $height =
null, $startGroup =
false)
963 $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption);
964 $width = $width ==
null ? 120 : $width;
965 $height = $height ==
null ? 25 : $height;
967 return $this->
createControl($parent, RadioButton, (
string)$caption, $xPos, $yPos, $width, $height, $startGroup ? WBC_GROUP :
null, $checked ? 1 : 0);
984 public function createButton($parent, $caption, $xPos, $yPos, $width =
null, $height =
null, $style =
null, $params =
null)
986 $width = $width ==
null ? 80 : $width;
987 $height = $height ==
null ? 25 : $height;
989 return $this->
createControl($parent, PushButton, $caption, $xPos, $yPos, $width, $height, $style, $params);
1006 public function createProgressBar($parent, $max, $xPos, $yPos, $width =
null, $height =
null, $style =
null, $params =
null)
1010 $width = $width ==
null ? 200 : $width;
1011 $height = $height ==
null ? 15 : $height;
1014 $this->
setRange($progressBar[self::CTRL_OBJ], 0, $max);
1015 $this->gauge[$progressBar[self::CTRL_OBJ]] = 0;
1017 return $progressBar;
1029 return $this->
callWinBinder(
'wb_get_value', array($wbobject));
1043 return $this->
callWinBinder(
'wb_set_range', array($wbobject, $min, $max));
1064 if ($progressBar !=
null && isset($progressBar[self::CTRL_OBJ]) && isset($this->gauge[$progressBar[self::CTRL_OBJ]])) {
1065 if (strval($value) == self::INCR_PROGRESS_BAR) {
1066 $value = $this->gauge[$progressBar[self::CTRL_OBJ]] + 1;
1068 if (is_numeric($value)) {
1069 $this->gauge[$progressBar[self::CTRL_OBJ]] = $value;
1073 $this->
callWinBinder(
'wb_set_value', array($progressBar[self::CTRL_OBJ], $value),
true);
1088 return $this->
callWinBinder(
'wb_set_value', array($wbobject, $content));
1109 $this->
setRange($progressBar[self::CTRL_OBJ], 0, $max);
1122 return $this->
messageBox($message, self::BOX_INFO, $title);
1138 $message = str_replace(self::NEW_LINE, PHP_EOL, $message);
1141 strlen($message) < 64 ? str_pad($message, 64) : $message,
1142 $title ==
null ? $this->defaultTitle : $this->defaultTitle .
' - ' . $title,
1159 return $this->
messageBox($message, self::BOX_OK, $title);
1172 return $this->
messageBox($message, self::BOX_OKCANCEL, $title);
1185 return $this->
messageBox($message, self::BOX_QUESTION, $title);
1198 return $this->
messageBox($message, self::BOX_ERROR, $title);
1211 return $this->
messageBox($message, self::BOX_WARNING, $title);
1224 return $this->
messageBox($message, self::BOX_YESNO, $title);
1237 return $this->
messageBox($message, self::BOX_YESNOCANCEL, $title);
1257 global $bearsamppWinbinder;
1259 if ($bearsamppWinbinder->callback[$window][2] !=
null) {
1260 $bearsamppWinbinder->destroyTimer($window, $bearsamppWinbinder->callback[$window][2][0]);
1263 call_user_func_array(
1264 array($bearsamppWinbinder->callback[$window][0], $bearsamppWinbinder->callback[$window][1]),
1265 array($window, $id, $ctrl, $param1, $param2)
__winbinderEventHandler($window, $id, $ctrl, $param1, $param2)
static debug($data, $file=null)
static initClass($classInstance)
static getImagesPath($aetrayPath=false)
static getWinbinderLogFilePath($aetrayPath=false)
setCursor($wbobject, $type=self::CURSOR_ARROW)
messageBoxYesNoCancel($message, $title=null)
setHandler($wbobject, $classCallback, $methodCallback, $launchTimer=null)
createFont($fontName, $size=null, $color=null, $style=null)
drawLine($wbobject, $xStartPos, $yStartPos, $xEndPos, $yEndPos, $color, $height=1)
messageBox($message, $type, $title=null)
createProgressBar($parent, $max, $xPos, $yPos, $width=null, $height=null, $style=null, $params=null)
createButton($parent, $caption, $xPos, $yPos, $width=null, $height=null, $style=null, $params=null)
messageBoxError($message, $title=null)
destroyTimer($wbobject, $timerobject)
callWinBinder($function, $params=array(), $removeErrorHandler=false)
incrProgressBar($progressBar)
setImage($wbobject, $path)
setValue($wbobject, $content)
createAppWindow($caption, $width, $height, $style=null, $params=null)
exec($cmd, $params=null, $silent=false, $wait=true, $showWindow=false)
createInputText($parent, $value, $xPos, $yPos, $width=null, $height=null, $maxLength=null, $style=null, $params=null)
setArea($wbobject, $width, $height)
setStyle($wbobject, $style)
setProgressBarValue($progressBar, $value)
createControl($parent, $ctlClass, $caption, $xPos, $yPos, $width, $height, $style=null, $params=null)
setRange($wbobject, $min, $max)
drawText($parent, $caption, $xPos, $yPos, $width=null, $height=null, $font=null)
createNakedWindow($caption, $width, $height, $style=null, $params=null)
messageBoxWarning($message, $title=null)
messageBoxOk($message, $title=null)
createHyperLink($parent, $caption, $xPos, $yPos, $width=null, $height=null, $style=null, $params=null)
drawRect($parent, $xPos, $yPos, $width, $height, $color=15790320, $filled=true)
resetProgressBar($progressBar)
messageBoxInfo($message, $title=null)
setText($wbobject, $content)
createRadioButton($parent, $caption, $checked, $xPos, $yPos, $width=null, $height=null, $startGroup=false)
quoteWindowsArg(string $arg)
createEditBox($parent, $value, $xPos, $yPos, $width=null, $height=null, $style=null, $params=null)
sysDlgPath($parent, $title, $path=null)
messageBoxOkCancel($message, $title=null)
messageBoxQuestion($message, $title=null)
sysDlgOpen($parent, $title, $filter=null, $path=null)
setProgressBarMax($progressBar, $max)
createLabel($parent, $caption, $xPos, $yPos, $width=null, $height=null, $style=null, $params=null)
setMaxLength($wbobject, $length)
createTimer($wbobject, $wait=1000)
createWindow($parent, $wclass, $caption, $xPos, $yPos, $width, $height, $style=null, $params=null)
drawImage($wbobject, $path, $xPos=0, $yPos=0, $width=0, $height=0)
setEnabled($wbobject, $enabled=true)
messageBoxYesNo($message, $title=null)