MapBasic и все что с ним связаноМожет я не один такой?!
#202
Отправлено 23.10.2009, 22:34:29
Include "icons.def" Include "mapbasic.def" Declare Sub Main Declare Sub izmKil Sub Main Create ButtonPad "Мои кнопки" As ToolButton Icon MI_ICON_LINE DrawMode DM_CURSOR_LINE Cursor MI_CURSOR_CROSSHAIR Calling izmKil HelpMsg "Этот инструмент измеряет расстояние в км от точки до точки" Show End Sub Sub izmKil dim x1, y1, x2, y2 As Float If WindowInfo(FrontWindow(), WIN_INFO_TYPE) <> WIN_MAPPER Then Note "Инструмент используется только в окне Карты." Exit Sub End If If MapperInfo(FrontWindow(), MAPPER_INFO_EDIT_LAYER) = -1 Then Note "Нет редактируемого слоя" Exit Sub End If Set CoordSys Window FrontWindow() 'Запомнить место, в котором начал действовать инструмент: x1 = CommandInfo(CMD_INFO_X) y1 = CommandInfo(CMD_INFO_Y) 'Запомнить место, в котором отпущена кнопка мыши: x2 = CommandInfo(CMD_INFO_X2) y2 = CommandInfo(CMD_INFO_Y2) Create Line Into FrontWindow() (x1, y1) (x2, y2) Note Distance (x1, y1, x2, y2, "km") End SubНе могу понять в чем ошибка:(36) Found[FrontWindow] while searching for [(].
#203
Отправлено 23.10.2009, 23:34:47
Create Line [Into { Window window_id | Variable var_name }] (x1, y1) (x2, y2) [Pen ...]Пропущено ключевое слово Window
В верным будет вызов:
Create Line Into Window FrontWindow() (x1, y1) (x2, y2)
Сообщение отредактировал swatch: 23.10.2009, 23:36:07
#204
Отправлено 12.11.2009, 15:59:36
dim Сумма As float dim Сумма1 As float dim x As String dim n As Float Dialog Title "Сумма" Control StaticText Title "Введите несколько чисел" Control EditText Into Сумма Control EditText Into Сумма1 Control OkButton Title "Сумма" If CommandInfo(CMD_INFO_DLG_OK) Then Сумма = EditText Сумма1 = EditText n = Сумма + Сумма1 x = "Сумма" note x + n End IfЯ хочу написать простенькую прогу, которая вычисляет сумму чисел введённых в поля EditText, но не могу понять как, и в чем ошибка в коде. Пишет: "Не определена переменная или поле CMD_INFO_DLG_OK"
Сообщение отредактировал fredwriter: 12.11.2009, 16:00:47
#205
Отправлено 12.11.2009, 16:13:43
dim Сумма As float dim Сумма1 As float dim x As String dim n As Float Dialog Title "Сумма" Control StaticText Title "Введите несколько чисел" Control EditText Into Сумма Control EditText Into Сумма1 Control OkButton Title "Сумма" If CommandInfo(CMD_INFO_DLG_OK) Then ' Сумма = EditText ' Сумма1 = EditText n = Сумма + Сумма1 x = "Сумма" note x + n End If
2 строчки закаментируй просто
' Сумма = EditText ' Сумма1 = EditText
#206
Отправлено 12.11.2009, 16:14:39
А теперь кое что разъясню в предложении Into, что указывается в Dialog после Control EditText, компилятор уже присваивает введенное значение пользователем переменной Сумма и Сумма1, так что такие дела
Да и еще момент при вводе не числовых данных будет ошибка но так как это для тебя простенькая задача, то в этом смысла тоже нет, удачи!
Сообщение отредактировал Jismo: 12.11.2009, 16:25:08
#207
Отправлено 13.11.2009, 14:19:31
Как я понял из твоего объяснения (ничего, что на ты обращаюсь?) у меня в коде было две лишние строки с присваиванием, так как присваивание было произведено раньше, я всё исправил, даже с твоего ответа код скопировал, но всё равно непашет, а хотелось бы, чтобы было
Сообщение отредактировал fredwriter: 13.11.2009, 14:37:28
#208
Отправлено 13.11.2009, 16:44:09
Теперь по сути вопроса:
Я сделал так - весь код программы закинул внутрь процедуры и по нажатию на кнопку в меню происходил вызов твоей программы. У меня все работает. У тебя тоже должно все работать, скорее всего ты пропустил директиву:
Include "MapBasic.DEF"которая располагается в самом вверху программы
#209
Отправлено 13.11.2009, 16:54:35
А теперь усложним условие2Jismo: Лови быстрое решение. Ковычек ровно столько сколько нужно. Куда писать путь до CHM пояснять не буду
Run Program "cmd /c ""start ""wintitle"" ""C:\Program Files\MapInfo\Professional\mapinfow.chm"""""после вызова START в ковычках указывается заголовок будущего окна для CMD, который можно сделать пустым (все равно никто не увидит).
Необходимо чтобы запуск осуществлялся из директории, где находиться сама программа(к примеру прога лежит тут C:\Program Files\Myprogs\myprog.mbx и там же лежит и файл справки myhelp.chm), т.е не указывая полного пути до chm-файла(myhelp.chm).
Буквально не давно у меня получилось потом случайно не сохранил, а сегодня забыл как я этого добился, требуется хэлп по этому вопросу, желательно срочно , жду ответов!!!
ЗЫ: если спросите зачем мне это надо отвечаю: допустим я отдаю свою программу на обкатку, ну сделал инсталлятор, юзер установил прогу в неизвестную мне директорию, а chm-файл находится там же где и mbx-файл - это железно, вот такие дела...
#210
Отправлено 14.11.2009, 02:38:35
Использовать надо функцию ApplicationDirectory$() она возвращает имя каталога, в котором находится файл выполняющегося приложения.
'-----начало с декларацией sub main почикано Run Program "cmd /c ""start ""wintitle"" """+ApplicationDirectory$()+"myhelp.chm""""" '-----конец тоже почиканОт себя добавлю, что чтение документации - это сила.
Удачи.
#212
Отправлено 19.11.2009, 21:24:53
Можно ли в mapbasic со строкой работать также как и с массивом, в цикле?
Есть ли функция определения длины строки?
Как я знаю, в MapBasic можно объявить массив строкового типа,
и есть функция определения текущего размера массива.
Сообщение отредактировал fredwriter: 19.11.2009, 21:57:54
#213
Отправлено 20.11.2009, 03:04:31
Работать со строкой как с массивом в цикле можно, но не так просто, указывая индекс нужного элемента в скобочках. Для чтения символа в нужной позиции используем строковую функцию Mid$Можно ли в mapbasic со строкой работать также как и с массивом, в цикле?
Синтаксис
Mid$( string_expr, position, length )
string_expr – выражение, результат которого есть строка;
position – целочисленное выражение, результат которого есть номер первого символа, извлекаемого из строки;
length – целочисленное выражение, результат которого есть количество извлекаемых символов.
Если нужно изменять символы, "пританцовываем" еще с функциями Left$ и Right$ для выделения частей строки до и после интересующей позиции и делаем конкатенацию всех частей.
Синтаксис
Left$ ( string_expr, num_expr )
Возвращает левую часть строки, выделяя определенное количество символов из исходной.
Right$ ( string_expr, num_expr )
Извлекает из правой части строки определенное количество символов.
string_expr – строковое выражение;
num_expr – числовое выражение, результат которого ноль или более.
Да есть функция LenЕсть ли функция определения длины строки?
Синтаксис
Len( expr )
expr – выражение
Возвращает количество символов в строке или число байтов в переменной.
Пример надуманный, но для демонстрации работы со строками "а-ля массив" само то:
Declare Sub main Sub main Dim aaa As String * 10 Dim i As Integer aaa="0123456789" Print aaa For i = 1 To Len(aaa) ' перебираем все символы строки и заменяем их на символы со смещением 17 позиций по кодовой странице символов aaa = Left$(aaa,i-1) + Chr$(Asc( Mid$(aaa,i,1) )+17) + Right$(aaa, Len(aaa) - i) Next Print aaa ' на выходе получаем aaa = "ABCDEFGHIJ" End Sub
Удачи...
Сообщение отредактировал swatch: 20.11.2009, 03:06:34
#214
Отправлено 21.11.2009, 16:16:33
Если в диалоге несколько простых кнопок, то как определить какая из них нажата? Искал в руководстве не нашёл!!! Может быть плохо искал?
Мне нужно написать прогу калькулятор, которая вычисляет /,*,+,-.
Одно поле ввода, в него нужно ввести массив Float.
Причём после ввода каждого элемента массива пользователь должен нажать одну из кнопок /,*,-,+ следовательно определять каждый элемент массива нужно после нажатия пользователем одной из кнопок.
Если пользователь ввел сколько угодно значное число и затем нажал какую-то из кнопок /,*,-,+, то это число есть первый элемент массива.
Затем это число нужно запомнить и удалить из поля ввода,и пользователь должен ввести еще какое-то число(второй элемент массива), и в зависимости от кнопки, которую он нажал нужно произвести соответствующее действие, запомнить результат и если пользователь захотел еще раз и еще раз и еще раз ввести число, нажимая кнопки... короче делать с ними действия.
Я не могу понять как при вводе и чисел и нажатии кнопок определять их введенные числа, как элементы массива и вообще еще много непонятного.
Сообщение отредактировал fredwriter: 21.11.2009, 18:09:45
#215
Отправлено 22.11.2009, 00:17:31
Она возвращает идентификатор элемента диалога, к которому пользователь обращался последним.
---из документации---
Синтаксис
TriggerControl()
Величина, полученная в результате Целое число. Величина типа Integer.
Описание
Функция TriggerControl() используется только внутри процедуры-обработчика диалога, построенного при помощи оператора Dialog. Функция возвращает номер элемента диалога, который был присвоен ему при создании диалога параметром из предложения ID.
Каждый элемент диалога может вызывать процедуру-обработчик. Это могут быть разные процедуры, а может быть так, что несколько элементов содержат вызов одного и того же обработчика. В последнем случае имеет смысл определить, какой именно элемент диалога был выбран пользователем.
---end из документации---
Не понятно зачем нужно сохранять в массив введенные числа, если можно считать все на лету как на живом калькуляторе.
Предполагается следующий сценарий:
Рисум диалог, в нем поле ввода, 4 кнопки (+, -, *, /) и лейбл для вывода текущего значения.
На кнопки, поле ввода и лейбл присваиваем ID чтобы потом можно было различать их с помощью описанной выше функции.
Это можно сделать определениями (define) для читабельности, например:
Define btnPlus 10 Define btnMinus 20 Define btnMul 30 Define btnDiv 40 Define edtInput 100 Define lblResult 200Затем при описании контролов используем эти определения:
Control Button ID btnPlus '<-------------- Title "+" Position 119, 54 Width 50 Height 15 Calling btnActionClick ' вешаем общий обработчикДля хранения текущего значения и необходимого действия опишем переменные в том же модуле, где описываем диалог:
Dim fResult As Float Dim iAction As IntegerПеред вызовом диалога значения переменных обнуляем.
Теперь самое интересное - описание процедурки обработчика btnActionClick примерно следующее:
Declare Sub btnActionClick Sub btnActionClick Dim fValue As Float Dim curAction As Integer Value = ReadControlValue(edtInput) 'по хорошему нужно читать сначала в строку потом с проверкой переводить в float curAction = TriggerControl() 'определяем какую кнопу нажали If iAction = 0 then 'первый раз нажали кнопку действий fResult = fValue 'запоминаем первый операнд iAction = curAction 'запоминаем какую операцию нужно сделать Else Do Case iAction 'выбираем действие по предыдущему нажатию Case btnPlus fResult = fResult + fValue ' выполняем сложение iAction = curAction 'запоминаем какую операцию нужно сделать в следующий раз Case btnMinus ' далее пишем аналогичные обработчики для остальных кнопок Case btnMul Case btnDiv End Case End If Alter Control edtInput Value "" ' очищаем поле ввода Alter Control lblResult Title fResult ' отображаем в контроле Label текущее значение после выполнения последнего действия End SubЧто-то в таком роде, писал код без проверки компилятором, возможны опечатки.
Если нужно хранить все введенное в массиве, лучше использовать массив заранее большой длины, т.к. если каждый раз его увеличивать функцией ReDim придется сохранять уже введенные элементы и затем переносить их обратно, т.к. после изменения длины массива значения теряются.
Эти действия можно приписать в конец процедуры btnActionClick после выражений Alter..., значения для вставки в массив брать из переменной fValue.
Удачи...
Сообщение отредактировал swatch: 22.11.2009, 00:21:04
#216
Отправлено 22.11.2009, 12:23:00
Dim fResult As Float Dim iAction As Integer Dim fArray() As Float Declare Sub btnActionClick Sub btnActionClick Dim fValue As Float Dim curAction As Integer Dim fBackupArray() As Float Dim iIndex As Integer fValue = ReadControlValue(edtInput) curAction = TriggerControl() If iAction = 0 then fResult = fValue iAction = curAction Else Do Case iAction Case btnPlus fResult = fResult + fValue iAction = curAction Case btnMinus fResult = fResult - fValue iAction = curAction Case btnMul fResult = fResult * fValue iAction = curAction Case btnDiv fResult = fResult / fValue iAction = curAction End Case End If Alter Control edtInput Value "" Alter Control lblResult Title Str$(fResult) ' Сохраняем данные масива перед изменением размера Redim fBackupArray(UBound(fArray)+1) For iIndex = 1 To UBound(fArray) fBackupArray(iIndex) = fArray(iIndex) Next ' Изменяем размер и восстанавливаем данные Redim fArray(UBound(fBackupArray)) For iIndex = 1 To UBound(fArray)-1 fArray(iIndex) = fBackupArray(iIndex) Next ' записываем в конец нужное значение, единственно из описания не понял ' что нужно запомнить в массиве: промежуточные результаты или введенные значения ' если второе, то вместо fResult нужно взять fValue iIndex = UBound(fArray) fArray(iIndex) = fResult End Sub
#218
Отправлено 22.11.2009, 19:50:32
И можно ли сделать так, чтобы поле ввода всегда было активно?
Что использовать в качестве лейбла? Я использую StaticText
Мне кажется, лучше выводить результат в это же поле ввода. Стирать его из памяти только в том случае, если пользователь сам его стёр из поля. В противном случае если пользователь не стёр его, а просто начал писать другое число, то стереть и запомнить это и делать с ним действия, в соответствии с действиями пользователя. И вообще может быть сделать кнопки с цифрами?... Шутка ... , а может быть и нет
PS: Я сам иногда понимаю значение мною написанного только через некоторое время
Сообщение отредактировал fredwriter: 22.11.2009, 22:15:27
#219
Отправлено 23.11.2009, 11:10:02
Чтобы поле ввода всегда было активно сделать можно, но не средствами MB. Для этого нужно импортировать функции WinAPI (по-моему SendMessage и FindWindow) и использовать их после нажатия кнопки действий устанавливая фокус ввода в нужное место.
Куда выводить - это ваше дело. ИМХО здесь вообще логики не видно исходя из постановки задачи.
Насчет кнопок с цифрами, когда-то на просторах Интернета мне попадалась реализация калькулятора на MB. Поищите и возможно будет Вам счастие безграничное
Количество пользователей, читающих эту тему: 7
пользователей: 0, неизвестных прохожих: 7, скрытых пользователей: 0