82 $this->countCtrls = 1000;
83 $this->callback = array();
97 public function createAppWindow($caption, $width, $height, $style =
null, $params =
null): mixed
99 return $this->
createWindow(
null, AppWindow, $caption, WBC_CENTER, WBC_CENTER, $width, $height, $style, $params);
117 public function createWindow($parent, $wclass, $caption, $xPos, $yPos, $width, $height, $style =
null, $params =
null): mixed
122 $parent = $parent ===
null ? 0 : $parent;
125 $style = $style ===
null ? 0 : $style;
126 $params = $params ===
null ? 0 : $params;
129 $this->
writeLog(
'Creating window: class=' . $wclass .
', caption=' . $caption .
', pos=(' . $xPos .
',' . $yPos .
'), size=(' . $width .
'x' . $height .
'), style=' . $style .
', params=' . $params);
131 $caption = empty($caption) ? $this->defaultTitle : $this->defaultTitle .
' - ' . $caption;
132 $window = $this->
callWinBinder(
'wb_create_window', array($parent, $wclass, $caption, $xPos, $yPos, $width, $height, $style, $params));
134 if ($window ===
false || $window ===
null) {
135 $this->
writeLog(
'ERROR: Failed to create window - wb_create_window returned: ' . var_export($window,
true));
137 if (!extension_loaded(
'winbinder')) {
138 $this->
writeLog(
'ERROR: WinBinder extension is not loaded!');
141 if (!function_exists(
'wb_create_window')) {
142 $this->
writeLog(
'ERROR: wb_create_window function does not exist!');
145 $this->
writeLog(
'Window created successfully: handle=' . $window);
163 private function callWinBinder($function, $params = array(), $removeErrorHandler =
false): mixed
166 if (function_exists($function)) {
167 if ($removeErrorHandler) {
169 $oldErrorLevel = error_reporting(0);
170 $result = @call_user_func_array($function, $params);
171 error_reporting($oldErrorLevel);
173 $result = call_user_func_array($function, $params);
190 if ($wbobject ===
null) {
191 error_log(
'Error: $wbobject is null.');
196 if (!file_exists($path)) {
197 error_log(
'Error: Image file does not exist at path: ' . $path);
202 return $this->
callWinBinder(
'wb_set_image', array($wbobject, $path));
216 public function createNakedWindow($caption, $width, $height, $style =
null, $params =
null): mixed
218 $window = $this->
createWindow(
null, NakedWindow, $caption, WBC_CENTER, WBC_CENTER, $width, $height, $style, $params);
219 $this->
setArea($window, $width, $height);
233 public function setArea($wbobject, $width, $height): mixed
235 return $this->
callWinBinder(
'wb_set_area', array($wbobject, WBC_TITLE, 0, 0, $width, $height));
252 $windowTitle = $this->
getText($window);
263 while ($attempt < $maxAttempts && !$destroyed) {
273 $this->
exec(
'taskkill',
'/FI "WINDOWTITLE eq ' . $windowTitle .
'" /F',
true);
277 if (!empty($currentPid)) {
278 $this->
exec(
'taskkill',
'/PID ' . $currentPid .
' /T /F',
true);
279 $this->
writeLog(
'Force-killed PID: ' . $currentPid .
' for window: ' . $window);
284 $this->
callWinBinder(
'wb_destroy_window', array($window),
true);
304 return $this->
callWinBinder(
'wb_get_text', array($wbobject));
320 $text = $this->
callWinBinder(
'wb_get_text', array($window),
true);
321 return ($text !==
false);
346 public function exec($cmd, $params =
null, $silent =
false, $wait =
true): mixed
349 if (is_array($params)) {
351 foreach ($params as $arg) {
354 $params = implode(
' ', $quotedParams);
361 $wsh =
new COM(
'WScript.Shell');
362 $fullCmd =
'"' . $cmd .
'"' . (empty($params) ?
'' :
' ' . $params);
364 $exitCode = $wsh->Run($fullCmd, 0, $wait);
365 $this->
writeLog(
'exec (silent via COM): ' . $fullCmd .
' [ExitCode: ' . $exitCode .
']');
366 return $exitCode === 0;
367 }
catch (Throwable $e) {
368 $this->
writeLog(
'exec (silent via COM) failed: ' . $e->getMessage() .
'. Falling back to PowerShell.');
370 $psCmd =
'Start-Process -FilePath \'' . str_replace(
"'",
"''", $cmd) .
'\'';
371 if (!empty($params)) {
372 $psCmd .=
' -ArgumentList \'' . str_replace(
"'",
"''", $params) .
'\'';
374 $psCmd .=
' -WindowStyle Hidden';
378 $encodedCmd = base64_encode(mb_convert_encoding($psCmd,
'UTF-16LE',
'UTF-8'));
379 $cmd =
'powershell.exe';
380 $params =
'-WindowStyle Hidden -ExecutionPolicy Bypass -EncodedCommand ' . $encodedCmd;
384 $this->
writeLog(
'exec: ' . $cmd .
' ' . $params);
386 return $this->
callWinBinder(
'wb_exec', array($cmd, $params));
409 if (preg_match(
'/[\s"&|<>^()]/', $arg)) {
411 $escaped = str_replace(
'"',
'""', $arg);
412 return '"' . $escaped .
'"';
448 return $this->
callWinBinder(
'wb_refresh', array($wbobject,
true));
460 return $this->
callWinBinder(
'wb_get_system_info', array($info));
475 public function drawImage($wbobject, $path, $xPos = 0, $yPos = 0, $width = 0, $height = 0): mixed
477 $image = $this->
callWinBinder(
'wb_load_image', array($path));
478 if ($image ===
null) {
482 return $this->
callWinBinder(
'wb_draw_image', array($wbobject, $image, $xPos, $yPos, $width, $height));
498 public function drawText($parent, $caption, $xPos, $yPos, $width =
null, $height =
null, $font =
null)
501 $caption = $caption ===
null ?
'' : $caption;
502 $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption);
503 $width = $width ==
null ? 120 : $width;
504 $height = $height ==
null ? 25 : $height;
506 return $this->
callWinBinder(
'wb_draw_text', array($parent, $caption, $xPos, $yPos, $width, $height, $font));
522 public function drawRect($parent, $xPos, $yPos, $width, $height, $color = 15790320, $filled =
true)
524 return $this->
callWinBinder(
'wb_draw_rect', array($parent, $xPos, $yPos, $width, $height, $color, $filled));
540 public function drawLine($wbobject, $xStartPos, $yStartPos, $xEndPos, $yEndPos, $color, $height = 1)
542 return $this->
callWinBinder(
'wb_draw_line', array($wbobject, $xStartPos, $yStartPos, $xEndPos, $yEndPos, $color, $height));
555 public function createFont($fontName, $size =
null, $color =
null, $style =
null)
557 return $this->
callWinBinder(
'wb_create_font', array($fontName, $size, $color, $style));
567 public function wait($wbobject =
null)
569 return $this->
callWinBinder(
'wb_wait', array($wbobject),
true);
582 return $this->
callWinBinder(
'wb_destroy_timer', array($wbobject, $timerobject));
610 public function setHandler($wbobject, $classCallback, $methodCallback, $launchTimer =
null)
612 if ($launchTimer !=
null) {
613 $launchTimer = $this->
createTimer($wbobject, $launchTimer);
616 $this->callback[$wbobject] = array($classCallback, $methodCallback, $launchTimer);
618 return $this->
callWinBinder(
'wb_set_handler', array($wbobject,
'__winbinderEventHandler'));
634 self::CTRL_ID => $this->countCtrls,
635 self::CTRL_OBJ => $this->
callWinBinder(
'wb_create_timer', array($wbobject, $this->countCtrls, $wait))
650 $content = $content ===
null ?
'' : $content;
651 $content = str_replace(self::NEW_LINE, PHP_EOL, $content);
653 return $this->
callWinBinder(
'wb_set_text', array($wbobject, $content));
675 return $this->
callWinBinder(
'wb_set_focus', array($wbobject));
687 return $this->
callWinBinder(
'wb_get_enabled', array($wbobject));
712 return $this->
callWinBinder(
'wb_set_enabled', array($wbobject, $enabled));
725 return $this->
callWinBinder(
'wb_set_style', array($wbobject, $style));
739 return $this->
callWinBinder(
'wb_sys_dlg_path', array($parent, $title, $path));
752 public function sysDlgOpen($parent, $title, $filter =
null, $path =
null)
754 return $this->
callWinBinder(
'wb_sys_dlg_open', array($parent, $title, $filter, $path));
771 public function createLabel($parent, $caption, $xPos, $yPos, $width =
null, $height =
null, $style =
null, $params =
null)
773 $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption);
774 $width = $width ==
null ? 120 : $width;
775 $height = $height ==
null ? 25 : $height;
777 return $this->
createControl($parent, Label, $caption, $xPos, $yPos, $width, $height, $style, $params);
795 public function createControl($parent, $ctlClass, $caption, $xPos, $yPos, $width, $height, $style =
null, $params =
null)
800 $style = $style ===
null ? 0 : $style;
801 $params = $params ===
null ? 0 : $params;
804 self::CTRL_ID => $this->countCtrls,
805 self::CTRL_OBJ => $this->
callWinBinder(
'wb_create_control', array(
835 public function createInputText($parent, $value, $xPos, $yPos, $width =
null, $height =
null, $maxLength =
null, $style =
null, $params =
null)
838 $value = $value ===
null ?
'' : $value;
839 $value = str_replace(self::NEW_LINE, PHP_EOL, $value);
840 $width = $width ==
null ? 120 : $width;
841 $height = $height ==
null ? 25 : $height;
842 $inputText = $this->
createControl($parent, EditBox, (
string)$value, $xPos, $yPos, $width, $height, $style, $params);
843 if (is_numeric($maxLength) && $maxLength > 0) {
844 $this->
setMaxLength($inputText[self::CTRL_OBJ], $maxLength);
862 return $this->
callWinBinder(
'wb_send_message', array($wbobject, 0x00c5, $length, 0),
true);
879 public function createEditBox($parent, $value, $xPos, $yPos, $width =
null, $height =
null, $style =
null, $params =
null)
881 $value = str_replace(self::NEW_LINE, PHP_EOL, $value);
882 $width = $width ==
null ? 540 : $width;
883 $height = $height ==
null ? 340 : $height;
884 $editBox = $this->
createControl($parent, RTFEditBox, (
string)$value, $xPos, $yPos, $width, $height, $style, $params);
903 public function createHyperLink($parent, $caption, $xPos, $yPos, $width =
null, $height =
null, $style =
null, $params =
null)
905 $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption);
906 $width = $width ==
null ? 120 : $width;
907 $height = $height ==
null ? 15 : $height;
908 $hyperLink = $this->
createControl($parent, HyperLink, (
string)$caption, $xPos, $yPos, $width, $height, $style, $params);
909 $this->
setCursor($hyperLink[self::CTRL_OBJ], self::CURSOR_FINGER);
922 public function setCursor($wbobject, $type = self::CURSOR_ARROW)
924 return $this->
callWinBinder(
'wb_set_cursor', array($wbobject, $type));
941 public function createRadioButton($parent, $caption, $checked, $xPos, $yPos, $width =
null, $height =
null, $startGroup =
false)
943 $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption);
944 $width = $width ==
null ? 120 : $width;
945 $height = $height ==
null ? 25 : $height;
947 return $this->
createControl($parent, RadioButton, (
string)$caption, $xPos, $yPos, $width, $height, $startGroup ? WBC_GROUP :
null, $checked ? 1 : 0);
964 public function createButton($parent, $caption, $xPos, $yPos, $width =
null, $height =
null, $style =
null, $params =
null)
966 $width = $width ==
null ? 80 : $width;
967 $height = $height ==
null ? 25 : $height;
969 return $this->
createControl($parent, PushButton, $caption, $xPos, $yPos, $width, $height, $style, $params);
986 public function createProgressBar($parent, $max, $xPos, $yPos, $width =
null, $height =
null, $style =
null, $params =
null)
990 $width = $width ==
null ? 200 : $width;
991 $height = $height ==
null ? 15 : $height;
994 $this->
setRange($progressBar[self::CTRL_OBJ], 0, $max);
995 $this->gauge[$progressBar[self::CTRL_OBJ]] = 0;
1009 return $this->
callWinBinder(
'wb_get_value', array($wbobject));
1023 return $this->
callWinBinder(
'wb_set_range', array($wbobject, $min, $max));
1044 if ($progressBar !=
null && isset($progressBar[self::CTRL_OBJ]) && isset($this->gauge[$progressBar[self::CTRL_OBJ]])) {
1045 if (strval($value) == self::INCR_PROGRESS_BAR) {
1046 $value = $this->gauge[$progressBar[self::CTRL_OBJ]] + 1;
1048 if (is_numeric($value)) {
1049 $this->gauge[$progressBar[self::CTRL_OBJ]] = $value;
1053 $this->
callWinBinder(
'wb_set_value', array($progressBar[self::CTRL_OBJ], $value),
true);
1068 return $this->
callWinBinder(
'wb_set_value', array($wbobject, $content));
1089 $this->
setRange($progressBar[self::CTRL_OBJ], 0, $max);
1102 return $this->
messageBox($message, self::BOX_INFO, $title);
1118 $message = str_replace(self::NEW_LINE, PHP_EOL, $message);
1121 strlen($message) < 64 ? str_pad($message, 64) : $message,
1122 $title ==
null ? $this->defaultTitle : $this->defaultTitle .
' - ' . $title,
1139 return $this->
messageBox($message, self::BOX_OK, $title);
1152 return $this->
messageBox($message, self::BOX_OKCANCEL, $title);
1165 return $this->
messageBox($message, self::BOX_QUESTION, $title);
1178 return $this->
messageBox($message, self::BOX_ERROR, $title);
1191 return $this->
messageBox($message, self::BOX_WARNING, $title);
1204 return $this->
messageBox($message, self::BOX_YESNO, $title);
1217 return $this->
messageBox($message, self::BOX_YESNOCANCEL, $title);
1237 global $bearsamppWinbinder;
1239 if ($bearsamppWinbinder->callback[$window][2] !=
null) {
1240 $bearsamppWinbinder->destroyTimer($window, $bearsamppWinbinder->callback[$window][2][0]);
1243 call_user_func_array(
1244 array($bearsamppWinbinder->callback[$window][0], $bearsamppWinbinder->callback[$window][1]),
1245 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)
exec($cmd, $params=null, $silent=false, $wait=true)
incrProgressBar($progressBar)
setImage($wbobject, $path)
setValue($wbobject, $content)
createAppWindow($caption, $width, $height, $style=null, $params=null)
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)