Перейти к содержимому

Фотография

MapBasic и все что с ним связаноМожет я не один такой?!


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 388

#201
swatch

swatch
  • Частый гость
  • 99 сообщений
В любом случае играемся со START-ом :rolleyes:
  • 0

#202
fredwriter

fredwriter
  • Гость
  • 26 сообщений
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 [(].
  • 0

#203
swatch

swatch
  • Частый гость
  • 99 сообщений
Смотрим внимательно синтаксис вызова команды Create Line:
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

  • 0

#204
fredwriter

fredwriter
  • Гость
  • 26 сообщений
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

  • 0

#205
Jismo

Jismo
  • Свой человек
  • 975 сообщений
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

  • 0

#206
Jismo

Jismo
  • Свой человек
  • 975 сообщений
И еще желательно не пользоваться русскими буквами для обозначения имен переменных

А теперь кое что разъясню в предложении Into, что указывается в Dialog после Control EditText, компилятор уже присваивает введенное значение пользователем переменной Сумма и Сумма1, так что такие дела :spy:

Да и еще момент при вводе не числовых данных будет ошибка но так как это для тебя простенькая задача, то в этом смысла тоже нет, удачи!

Сообщение отредактировал Jismo: 12.11.2009, 16:25:08

  • 0

#207
fredwriter

fredwriter
  • Гость
  • 26 сообщений
Огромное спасибо Jismo :lol:, но я обнаружил, что прога все равно не пашет и выдаёт ту же ошибку :)
Как я понял из твоего объяснения (ничего, что на ты обращаюсь?) у меня в коде было две лишние строки с присваиванием, так как присваивание было произведено раньше, я всё исправил, даже с твоего ответа код скопировал, но всё равно непашет, :) а хотелось бы, чтобы было :)

Сообщение отредактировал fredwriter: 13.11.2009, 14:37:28

  • 0

#208
Jismo

Jismo
  • Свой человек
  • 975 сообщений
Ничего страшного если будем общаться на "ты" :dandy:.

Теперь по сути вопроса:
Я сделал так - весь код программы закинул внутрь процедуры и по нажатию на кнопку в меню происходил вызов твоей программы. У меня все работает. У тебя тоже должно все работать, скорее всего ты пропустил директиву:
Include "MapBasic.DEF"
которая располагается в самом вверху программы
  • 0

#209
Jismo

Jismo
  • Свой человек
  • 975 сообщений

2Jismo: Лови быстрое решение. Ковычек ровно столько сколько нужно. Куда писать путь до CHM пояснять не буду :lol:

Run Program "cmd /c ""start  ""wintitle"" ""C:\Program Files\MapInfo\Professional\mapinfow.chm"""""
после вызова START в ковычках указывается заголовок будущего окна для CMD, который можно сделать пустым (все равно никто не увидит).

А теперь усложним условие :dandy:
Необходимо чтобы запуск осуществлялся из директории, где находиться сама программа(к примеру прога лежит тут C:\Program Files\Myprogs\myprog.mbx и там же лежит и файл справки myhelp.chm), т.е не указывая полного пути до chm-файла(myhelp.chm).

Буквально не давно у меня получилось потом случайно не сохранил, а сегодня забыл как я этого добился, требуется хэлп по этому вопросу, желательно срочно :lol:, жду ответов!!!

ЗЫ: если спросите зачем мне это надо отвечаю: допустим я отдаю свою программу на обкатку, ну сделал инсталлятор, юзер установил прогу в неизвестную мне директорию, а chm-файл находится там же где и mbx-файл - это железно, вот такие дела...
  • 0

#210
swatch

swatch
  • Частый гость
  • 99 сообщений
2Jismo:
Использовать надо функцию ApplicationDirectory$() она возвращает имя каталога, в котором находится файл выполняющегося приложения.
'-----начало с декларацией sub main почикано
Run Program "cmd /c ""start  ""wintitle"" """+ApplicationDirectory$()+"myhelp.chm"""""
'-----конец тоже почикан
От себя добавлю, что чтение документации - это сила.
Удачи. :-)
  • 0

#211
Jismo

Jismo
  • Свой человек
  • 975 сообщений
2swatch
да да вы правы как всегда ;)
спс еще раз за наставление :-)
  • 0

#212
fredwriter

fredwriter
  • Гость
  • 26 сообщений
Здравствуйте
Можно ли в mapbasic со строкой работать также как и с массивом, в цикле?
Есть ли функция определения длины строки?
Как я знаю, в MapBasic можно объявить массив строкового типа,
и есть функция определения текущего размера массива.

Сообщение отредактировал fredwriter: 19.11.2009, 21:57:54

  • 0

#213
swatch

swatch
  • Частый гость
  • 99 сообщений
2fredwriter: Привет, создается такое впечатление, как-будто все игнорируют документацию по MB :rolleyes:

Можно ли в mapbasic со строкой работать также как и с массивом, в цикле?

Работать со строкой как с массивом в цикле можно, но не так просто, указывая индекс нужного элемента в скобочках. Для чтения символа в нужной позиции используем строковую функцию Mid$
Синтаксис
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

  • 0

#214
fredwriter

fredwriter
  • Гость
  • 26 сообщений
Спасибо за информацию swatch :rotate: Еще один вопрос:
Если в диалоге несколько простых кнопок, то как определить какая из них нажата? Искал в руководстве не нашёл!!! Может быть плохо искал? :rotate:
Мне нужно написать прогу калькулятор, которая вычисляет /,*,+,-.
Одно поле ввода, в него нужно ввести массив Float.
Причём после ввода каждого элемента массива пользователь должен нажать одну из кнопок /,*,-,+ следовательно определять каждый элемент массива нужно после нажатия пользователем одной из кнопок.
Если пользователь ввел сколько угодно значное число и затем нажал какую-то из кнопок /,*,-,+, то это число есть первый элемент массива.
Затем это число нужно запомнить и удалить из поля ввода,и пользователь должен ввести еще какое-то число(второй элемент массива), и в зависимости от кнопки, которую он нажал нужно произвести соответствующее действие, запомнить результат и если пользователь захотел еще раз и еще раз и еще раз ввести число, нажимая кнопки... короче делать с ними действия.
Я не могу понять как при вводе и чисел и нажатии кнопок определять их введенные числа, как элементы массива и вообще еще много непонятного.

Сообщение отредактировал fredwriter: 21.11.2009, 18:09:45

  • 0

#215
swatch

swatch
  • Частый гость
  • 99 сообщений
Первое что приходит в голову - это пользовать функцию TriggerControl()
Она возвращает идентификатор элемента диалога, к которому пользователь обращался последним.
---из документации---
Синтаксис
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.
Удачи... :laugh:

Сообщение отредактировал swatch: 22.11.2009, 00:21:04

  • 0

#216
swatch

swatch
  • Частый гость
  • 99 сообщений
Поправочка на свежую голову + проверенный код
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

  • 0

#217
fredwriter

fredwriter
  • Гость
  • 26 сообщений
Огромное спасибо тебе, swatch :-).

Сообщение отредактировал fredwriter: 22.11.2009, 19:49:47

  • 0

#218
fredwriter

fredwriter
  • Гость
  • 26 сообщений
А можно ли увеличить шрифт титла для кнопки?
И можно ли сделать так, чтобы поле ввода всегда было активно? :-)
Что использовать в качестве лейбла? Я использую StaticText :cry:
Мне кажется, лучше выводить результат в это же поле ввода. Стирать его из памяти только в том случае, если пользователь сам его стёр из поля. В противном случае если пользователь не стёр его, а просто начал писать другое число, то стереть и запомнить это и делать с ним действия, в соответствии с действиями пользователя. И вообще может быть сделать кнопки с цифрами?... Шутка ... , а может быть и нет :spy:

PS: Я сам иногда понимаю значение мною написанного только через некоторое время

Сообщение отредактировал fredwriter: 22.11.2009, 22:15:27

  • 0

#219
swatch

swatch
  • Частый гость
  • 99 сообщений
Шрифт для надписи на кнопке индивидуально изменить нельзя. Он берется из системных настроек оформления Windows.
Чтобы поле ввода всегда было активно сделать можно, но не средствами MB. Для этого нужно импортировать функции WinAPI (по-моему SendMessage и FindWindow) и использовать их после нажатия кнопки действий устанавливая фокус ввода в нужное место.
Куда выводить - это ваше дело. ИМХО здесь вообще логики не видно исходя из постановки задачи.
Насчет кнопок с цифрами, когда-то на просторах Интернета мне попадалась реализация калькулятора на MB. Поищите и возможно будет Вам счастие безграничное :rotate:
  • 0

#220
fredwriter

fredwriter
  • Гость
  • 26 сообщений
Большое спасибо тебе, swatch
  • 0


Количество пользователей, читающих эту тему: 1

пользователей: 0, неизвестных прохожих: 1, скрытых пользователей: 0

Размещение рекламы на сайте     Предложения о сотрудничестве     Служба поддержки пользователей

© 2011-2022 vse.kz. При любом использовании материалов Форума ссылка на vse.kz обязательна.