Пишем игру Минер. Обработка событий ActiveX в 1С

Программирование - Практика программирования

Пример демонстрирует обработку событий генерируемых компонентой ActiveX в 1С.

Открываем  и создаем проект аналогично описаном в предыдущей статье  //infostart.ru/public/625457/.

Для хранения изображений колоды карт будем использовать компонент TImage. Кидаем его на форму и подгружаем изображения. Свойство Visible = false

Открываем Type Library и добавляем 3 метода:

AddCell  - добавляем ячейку

ChangeImage - поменять ячейку

ClearResource - Очищаем ресурсы с формы

Добавляем СОБЫТИЕ

Кодим:

Создаем класс

TCell = class
  Public
    Image : TImage;
    Row: Integer;
    Column: Integer;
    Par : Tw0rmMine;
    NameClass : string;
    Procedure OnRightClickImage(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  Constructor Create(x, y, iRow, iCol : Integer; iName: string);
  End;
procedure Tw0rmMine.MyEvent(Row, Column: Integer; Button, Name: string);
begin
  if FEvents <> nil then FEvents.OnClickCell(Row, Column, Button, Name);
end;

{ TCell }


constructor TCell.Create(x, y, iRow, iCol: Integer; iName: string);
begin
  x := x;
  y := y;
  Row := iRow;
  Column := iCol;
  NameClass := iName

end;


procedure TCell.OnRightClickImage(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Butt : String;

begin

  if Button = controls.mbRight then
    begin
      Butt := 'btRight';
    end;
  if Button = controls.mbLeft then
    begin
      Butt := 'btLeft';
    end;

    Par.MyEvent(Row, Column, Butt, NameClass); //!!!-ГЕНЕРИРУЕМ СОБЫТИЕ ДЛЯ 1С

end;


//Прорисовываем ячейку
procedure Tw0rmMine.AddCell(x, y, Row, Column: Integer;
  const Name: WideString);
var
  Cell : TCell;
const
  h=30; //Высота изображения
begin
  Cell := TCell.Create(x,y,Row,Column, Name);
  cell.Image := TImage.Create(Self);
  cell.Image.Parent:= Self;
  cell.Image.Left:=x;
  cell.Image.Top:=y;
  cell.Image.Width:=h;
  cell.Image.Height:=h;
  cell.Image.Name := Name;
  cell.Image.Canvas.CopyRect(Rect(0, 0, h, h), Image1.Canvas, Rect(column*h ,row*h, (column*h)+h, (row*h)+h));
  cell.Image.OnMouseDown := cell.OnRightClickImage;
  cell.Par := Self;
end;


//Меняем изображение в ячейке
procedure Tw0rmMine.ChangeImage(const Name: WideString; Row,
  Column: Integer);
Var
  img : TImage;
const
  h=30; //Высота изображения
begin
  img:=(FindComponent(Name)) as Timage;
  img.Canvas.CopyRect(Rect(0, 0, h, h), Image1.Canvas, Rect(column*h ,row*h, (column*h)+h, (row*h)+h));
end;

//Очищаем ресурсы 
procedure Tw0rmMine.ClearResource;
var i : integer;
begin
for i:= ComponentCount-1 downto 0 do
 begin
  If Components[i].Name <> 'Image1' then  Components[i].Free;
 end;
end;

Регистрируем компоненту.

Открываем 1С создаем обработку. Накидываем контролы. Видим, что появилось наше событие:

Кодим:

Перем МассивЯчеек;
Перем МассивИменЯчеек;
Перем МассивСостояниеЯчейки;
Перем МассивСостоянияФлагаЯчейки;
Перем ИдМины;

Процедура КнопкаВыполнитьНажатие(Кнопка)
	ЭлементыФормы.ЭлементУправления1.AddCell(0,0,1,2, "s1");
	ЭлементыФормы.ЭлементУправления1.AddCell(0,30,0,0, "s2");
КонецПроцедуры

Процедура ЭлементУправления1OnClickCell(Элемент, Row, Column, Button, Name)
	
	СпецификацияЯчейки = СтрЗаменить(Name, "_", Символы.ПС);
	Строк = Число(СтрПолучитьСтроку (СпецификацияЯчейки, 2)) - 1;
	Колонка = Число(СтрПолучитьСтроку (СпецификацияЯчейки, 3))-1;
	
	Если МассивСостояниеЯчейки[Строк][Колонка] =1 Тогда 
		Возврат;
	КонецЕсли;	
	
	Если Button = "btLeft" Тогда 
		
		ОбработатьГрафическийВыводЛеваяКнопка(Строк, Колонка, Name);
		
		Если МассивЯчеек[Строк][Колонка] = 0 Тогда
			ОбработатьПустуюЯчейку(Строк, Колонка);
			
			Выход = Ложь;
			
			Пока Выход = Ложь Цикл 
				Выход = Истина;
				
				Для а = 0 по КоличествоСтрок-1 Цикл 
					Для б = 0 по КоличествоКолонок-1 Цикл 
						Если МассивСостояниеЯчейки[а][б] = 99 Тогда 
							ОбработатьПустуюЯчейку(а, б);
							МассивСостояниеЯчейки[а][б] = 1;
							Выход = Ложь;
						КонецЕсли;	
						
					КонецЦикла;	
				КонецЦикла;
			КонецЦикла;	
			
		КонецЕсли;
		
		МассивСостояниеЯчейки[Строк][Колонка] = 1;
				
	КонецЕсли;	
	
	
	Если Button = "btRight" Тогда
		
		МассивСостоянияФлагаЯчейки[Строк][Колонка] = МассивСостоянияФлагаЯчейки[Строк][Колонка] + 1;
		Если МассивСостоянияФлагаЯчейки[Строк][Колонка] > 2 Тогда 
			МассивСостоянияФлагаЯчейки[Строк][Колонка] = 0;	
		КонецЕсли;	
		
		ОбработатьГрафическийВыводПраваяКнопка(Строк, Колонка, Name);
	
	КонецЕсли;	
	
	ПроверитьИгру();
	
КонецПроцедуры

Процедура ПриОткрытии()
	КоличествоКолонок = 10;
	КоличествоСтрок   = 10;
	КоличествоМин     = 10;
КонецПроцедуры

Процедура СтартНажатие(Элемент)	
	ЭлементыФормы.КомпонентПоле.ClearResource();
	ИнициализироватьПоле();
	ПрорисоватьПоле();
	ИдБомбы = 999;
	
КонецПроцедуры

Процедура ИнициализироватьПоле()
	
	МассивЯчеек = Новый	Массив(КоличествоСтрок, КоличествоКолонок);
	МассивСостояниеЯчейки = Новый	Массив(КоличествоСтрок, КоличествоКолонок);
	МассивСостоянияФлагаЯчейки = Новый	Массив(КоличествоСтрок, КоличествоКолонок);
	
	//Инициализируем массив
	Для а = 0 по КоличествоСтрок-1 Цикл 
		Для б = 0 по КоличествоКолонок-1 Цикл 
			МассивЯчеек[а][б] = 0;
			МассивСостояниеЯчейки[а][б] = 0;
			МассивСостоянияФлагаЯчейки[а][б] =0;
		КонецЦикла;	
	КонецЦикла;	
	
	//Расставляем мины
	
	Для ии = 1 По КоличествоМин Цикл  
		
		МинаРасставлена = Ложь;
		
		Пока МинаРасставлена = Ложь Цикл 
			Колонка = ПолучитьСлучайноеЧисло(0, КоличествоСтрок-1);
			Ряд = ПолучитьСлучайноеЧисло(0, КоличествоКолонок-1);	

			Если МассивЯчеек[Ряд][Колонка] = 0 Тогда 
				МассивЯчеек[Ряд][Колонка] = ИдМины; //Ид мины в маасиве
				МинаРасставлена = Истина;
			КонецЕсли;	
		КонецЦикла;	
			
	КонецЦикла;	
	
	//Обрабатываем поле
	
	Для а = 0 по КоличествоСтрок-1 Цикл 
		Для б = 0 по КоличествоКолонок-1 Цикл 
			Если МассивЯчеек[а][б] = 0 Тогда 
				МассивЯчеек[а][б] = ПроверитьЯчейку(а,б);
			КонецЕсли;
		КонецЦикла;	
	КонецЦикла;	



КонецПроцедуры	

Процедура ПрорисоватьПоле()
	
	игрек = 0;
	МассивИменЯчеек = Новый	Массив(КоличествоСтрок, КоличествоКолонок);
	
	Для а = 0 по КоличествоСтрок-1 Цикл 
		икс = 0;
		Для б = 0 по КоличествоКолонок-1 Цикл 			
			имя = "Cell_" + СокрЛП(Формат(Число(а+1),"ЧГ=")) + "_" + СокрЛП(Формат(Число(б+1),"ЧГ="));
			МассивИменЯчеек[а][б] = имя;
			ЭлементыФормы.КомпонентПоле.AddCell(икс, игрек, 0, 0, имя);
			икс = икс + 30;
		КонецЦикла;
		игрек = игрек +30;
	КонецЦикла;	
	
КонецПроцедуры	

Функция ПолучитьСлучайноеЧисло(Мин,Макс) 

	//вместо Randomize 
	Для н = 1 По 100 Цикл 
		Уник = Новый УникальныйИдентификатор; 
	КонецЦикла; 

	//генерируем GUID 
	Уник = СокрЛП(Новый УникальныйИдентификатор); 

	//оставляем только цифры 
	Уник = СтрЗаменить(Уник,"-",""); 
	Уник = СтрЗаменить(Уник,"a",""); 
	Уник = СтрЗаменить(Уник,"b",""); 
	Уник = СтрЗаменить(Уник,"c",""); 
	Уник = СтрЗаменить(Уник,"d",""); 
	Уник = СтрЗаменить(Уник,"e",""); 
	Уник = СтрЗаменить(Уник,"f",""); 

//знаменатель должен иметь такое же количество нулей + 1 
	Знаменатель = 10; 
	Для н = 2 По (СтрДлина(СтрЗаменить(Уник,Символы.НПП,""))) Цикл 
		Знаменатель = Знаменатель * 10; 
	КонецЦикла; 

	Случ = Число(Уник) / Знаменатель; //здесь получается дробное случайное число от 0 до 1 

	//преобразуем его в случайное число из заданного интервала, округляем до целого 
	ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс); 

	Возврат ЧислоИзИнтервала; 

КонецФункции

Функция ПроверитьЯчейку(Строк, Колонка)
	
	счетчик = 0;
	
	Если Строк-1 >= 0 и Колонка-1 >=0 Тогда 
		Если МассивЯчеек[Строк-1][Колонка-1] = ИдМины Тогда 
			счетчик = счетчик + 1;	
		КонецЕсли;	
	КонецЕсли;	
	
	Если Колонка-1 >=0 Тогда
		Если МассивЯчеек[Строк][Колонка-1] = ИдМины Тогда 
			счетчик = счетчик + 1; 
		КонецЕсли;	
	КонецЕсли;	
	
	Если Строк+1 < КоличествоСтрок и Колонка-1 >=0 Тогда 
		Если МассивЯчеек[Строк+1][Колонка-1] = ИдМины Тогда 
			счетчик = счетчик + 1;	
		КонецЕсли;
	КонецЕсли;	

	Если Строк-1 >=0 Тогда 
		Если МассивЯчеек[Строк-1][Колонка] = ИдМины Тогда 
			счетчик = счетчик + 1;	
		КонецЕсли;
	КонецЕсли;	
	
	Если Строк+1 <КоличествоСтрок Тогда 
		Если МассивЯчеек[Строк+1][Колонка] = ИдМины Тогда 
			счетчик = счетчик + 1;	
		КонецЕсли;
	КонецЕсли;	
	
	
	Если Строк-1 >=0 и Колонка+1 < КоличествоКолонок Тогда 
		Если МассивЯчеек[Строк-1][Колонка+1] = ИдМины Тогда 
			счетчик = счетчик + 1;
		КонецЕсли;		
	КонецЕсли;
	
	Если Колонка+1 < КоличествоКолонок Тогда 
		Если МассивЯчеек[Строк][Колонка+1]= ИдМины Тогда 
			счетчик = счетчик + 1;
		КонецЕсли;	
	КонецЕсли;	
	
	Если Строк+1 < КоличествоСтрок и Колонка+1 < КоличествоКолонок Тогда 
		Если МассивЯчеек[Строк+1][Колонка+1] = ИдМины Тогда 
			счетчик = счетчик + 1;
		КонецЕсли;	
	КонецЕсли;
	
	Возврат(счетчик);
КонецФункции	

Процедура ОбработатьПустуюЯчейку(Строк, Колонка)
	
		МассивСостояниеЯчейки[Строк][Колонка] = 1;
	
		Если Строк-1 >= 0 и Колонка-1 >=0 Тогда  
			ОбработатьГрафическийВыводЛеваяКнопка(Строк-1, Колонка-1, МассивИменЯчеек[Строк-1][Колонка-1]);
			Если МассивЯчеек[Строк-1][Колонка-1] = 0 и МассивСостояниеЯчейки[Строк-1][Колонка-1] <> 1 Тогда
				МассивСостояниеЯчейки[Строк-1][Колонка-1] = 99;
			Иначе
				МассивСостояниеЯчейки[Строк-1][Колонка-1] = 1;	
			КонецЕсли;	
		КонецЕсли;	

		
		Если Колонка-1 >=0 Тогда 
			ОбработатьГрафическийВыводЛеваяКнопка(Строк, Колонка-1, МассивИменЯчеек[Строк][Колонка-1]);
			Если МассивЯчеек[Строк][Колонка-1] = 0 и МассивСостояниеЯчейки[Строк][Колонка-1] <> 1 Тогда	
				МассивСостояниеЯчейки[Строк][Колонка-1] = 99;
			Иначе
				МассивСостояниеЯчейки[Строк][Колонка-1] = 1;	
			КонецЕсли;	
		КонецЕсли;	
		
		Если Строк+1 < КоличествоСтрок и Колонка-1 >=0 Тогда 
			ОбработатьГрафическийВыводЛеваяКнопка(Строк+1, Колонка-1, МассивИменЯчеек[Строк+1][Колонка-1]);	
			Если МассивЯчеек[Строк+1][Колонка-1] = 0 и МассивСостояниеЯчейки[Строк+1][Колонка-1] <> 1 Тогда
				МассивСостояниеЯчейки[Строк+1][Колонка-1] = 99;
			Иначе
				МассивСостояниеЯчейки[Строк+1][Колонка-1] = 1;	
			КонецЕсли;
		КонецЕсли;	

		Если Строк-1 >=0 Тогда 
			ОбработатьГрафическийВыводЛеваяКнопка(Строк-1, Колонка, МассивИменЯчеек[Строк-1][Колонка]);	
			Если МассивЯчеек[Строк-1][Колонка] = 0 и МассивСостояниеЯчейки[Строк-1][Колонка] <> 1 Тогда 
				МассивСостояниеЯчейки[Строк-1][Колонка] = 99;
			Иначе
				МассивСостояниеЯчейки[Строк-1][Колонка] = 1;	
			КонецЕсли;
		КонецЕсли;	
		
		Если Строк+1 <КоличествоСтрок Тогда  
			ОбработатьГрафическийВыводЛеваяКнопка(Строк+1, Колонка, МассивИменЯчеек[Строк+1][Колонка]);	
			Если МассивЯчеек[Строк+1][Колонка] = 0 и МассивСостояниеЯчейки[Строк+1][Колонка] <> 1 Тогда	
				МассивСостояниеЯчейки[Строк+1][Колонка] = 99;
			Иначе
				МассивСостояниеЯчейки[Строк+1][Колонка] = 1;	
			КонецЕсли;
		КонецЕсли;	
		
		
		Если Строк-1 >=0 и Колонка+1 < КоличествоКолонок Тогда  
			ОбработатьГрафическийВыводЛеваяКнопка(Строк-1, Колонка+1, МассивИменЯчеек[Строк-1][Колонка+1]);	
			Если МассивЯчеек[Строк-1][Колонка+1] = 0 и МассивСостояниеЯчейки[Строк-1][Колонка+1] <> 1 Тогда	
				МассивСостояниеЯчейки[Строк-1][Колонка+1] = 99;
			Иначе
				МассивСостояниеЯчейки[Строк-1][Колонка+1] = 1;	
			КонецЕсли;		
		КонецЕсли;
		
		Если Колонка+1 < КоличествоКолонок Тогда  
			ОбработатьГрафическийВыводЛеваяКнопка(Строк, Колонка+1, МассивИменЯчеек[Строк][Колонка+1]);
			Если МассивЯчеек[Строк][Колонка+1]= 0 и МассивСостояниеЯчейки[Строк][Колонка+1] <> 1 Тогда	
				МассивСостояниеЯчейки[Строк][Колонка+1] = 99;
			Иначе 	
				МассивСостояниеЯчейки[Строк][Колонка+1] = 1;
			КонецЕсли;	
		КонецЕсли;	
		
		Если Строк+1 < КоличествоСтрок и Колонка+1 < КоличествоКолонок Тогда  
			ОбработатьГрафическийВыводЛеваяКнопка(Строк+1, Колонка+1, МассивИменЯчеек[Строк+1][Колонка+1]);	
			Если МассивЯчеек[Строк+1][Колонка+1] = 0 и МассивСостояниеЯчейки[Строк+1][Колонка+1] <> 1 Тогда	
				МассивСостояниеЯчейки[Строк+1][Колонка+1] = 99;
			Иначе
				МассивСостояниеЯчейки[Строк+1][Колонка+1] = 1;	
			КонецЕсли;	
		КонецЕсли;	

КонецПроцедуры

Процедура ОбработатьГрафическийВыводЛеваяКнопка(Строк, Колонка, Name)
	
		Если МассивЯчеек[Строк][Колонка] = ИдМины Тогда 
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 4, 0);
			Предупреждение("Вы проиграли!");
		КонецЕсли;	
		
		Если МассивЯчеек[Строк][Колонка] = 0 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 4, 1);
		КонецЕсли;  		
		
		Если МассивЯчеек[Строк][Колонка] = 1 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 1, 0);
		КонецЕсли;
		
		Если МассивЯчеек[Строк][Колонка] = 2 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 1, 1);
		КонецЕсли;
		
		Если МассивЯчеек[Строк][Колонка] = 3 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 1, 2);
		КонецЕсли;
		
		Если МассивЯчеек[Строк][Колонка] = 4 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 2, 0);
		КонецЕсли;
		
		Если МассивЯчеек[Строк][Колонка] = 5 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 2, 1);
		КонецЕсли;
		
		Если МассивЯчеек[Строк][Колонка] = 6 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 2, 2);
		КонецЕсли;
		
		Если МассивЯчеек[Строк][Колонка] = 7 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 3, 0);
		КонецЕсли;
		
		Если МассивЯчеек[Строк][Колонка] = 8 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 3, 1);
		КонецЕсли;
		
		МассивСостоянияФлагаЯчейки[Строк][Колонка] =0;
	
КонецПроцедуры	

Процедура ОбработатьГрафическийВыводПраваяКнопка(Строк, Колонка, Name)
	
		Если МассивСостоянияФлагаЯчейки[Строк][Колонка] = 0 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 0, 0);
		КонецЕсли;  		
		
		Если МассивСостоянияФлагаЯчейки[Строк][Колонка] = 1 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 0, 1);
		КонецЕсли;
		
		Если МассивСостоянияФлагаЯчейки[Строк][Колонка] = 2 Тогда
			ЭлементыФормы.КомпонентПоле.ChangeImage(Name, 0, 2);
		КонецЕсли;
	
КонецПроцедуры	
	
Процедура ПроверитьИгру()
	
	сч = 0;
		
	Для а = 0 по КоличествоСтрок-1 Цикл 
		Для б = 0 по КоличествоКолонок-1 Цикл 
			Если МассивЯчеек[а][б] = ИдМины и МассивСостоянияФлагаЯчейки[а][б] =1 Тогда 
				
				сч = сч + 1;
			
			КонецЕсли;
		КонецЦикла;	
	КонецЦикла;	
	
	Если сч = КоличествоМин Тогда 
		Предупреждение("Вы победили");
	КонецЕсли;	
		
КонецПроцедуры		
		
		

 

 

См. также

Комментарии
1. Дмитрий Васильев (user621724_Dimav1979) 202 29.05.17 10:55 Сейчас в теме
Исходники
Прикрепленные файлы:
miner.zip
sasha777666; monsterZE; ifal; netesoff; smirnov.es; +5 Ответить
2. Дмитрий Котов (rpgshnik) 89 29.05.17 11:09 Сейчас в теме
Картинки графики красивые, сам делал?
Прикрепленные файлы:
smirnov.es; +1 Ответить
3. Дмитрий Васильев (user621724_Dimav1979) 202 29.05.17 11:37 Сейчас в теме
(2) Картинки друг мой сделал - ДИМКА КОТ
корум; rpgshnik; +2 Ответить
4. Игорь Фелькер (Brawler) 328 29.05.17 18:52 Сейчас в теме
ActiveX загибается загибается, да никак не загнется, как и мерзопакостный Delphi)))
5. Дмитрий Васильев (user621724_Dimav1979) 202 30.05.17 02:40 Сейчас в теме
(4) слова недалёкого человека...учите матчасть и не пишите больше чепухи
smirnov.es; Deslime; CyberCerber; rpgshnik; ifal; +5 Ответить
8. Игорь Фелькер (Brawler) 328 30.05.17 07:06 Сейчас в теме
(5) Давайте без оскорблений! Технология ActiveX в моём понимании ещё жива только из-за большой тяги Microsoft к обратной совместимости. Да в некоторых случаях удобно её использовать, но вот в проведенном вами решении есть проблема. Без танцев с бубном не заставить работать под тем же линуксом. А по поводу Delphi, свой путь в профессию начинал с него когда-то, но потом быстро переметнулся на С# и не жалею. Сдаётся мне у вас предвзятое отношение к пользователям сего ресурса. Ошибочное я бы сказал, тут многие освоили не только программирование на 1С.
sasha777666; rpgshnik; +2 1 Ответить
9. Дмитрий Васильев (user621724_Dimav1979) 202 30.05.17 08:46 Сейчас в теме
(8) Учитесь выбирать, конкретный инструментарий под конкретную задачу! Неважно дельфи это 7 версии или XE последней версии...да это тяжело, но приходит с опытом. Если человек не в состоянии применить навыки - это не значит, что невозможно это сделать.
11. Игорь Фелькер (Brawler) 328 30.05.17 10:47 Сейчас в теме
(9) Учитесь не учить людей уму разуму
sasha777666; rpgshnik; +2 1 Ответить
6. Андрей Суханцов (&rew) 6 30.05.17 05:33 Сейчас в теме
Я, конечно, дико извиняюсь, но мне кажется что все-таки Сапёр!
rpgshnik; +1 Ответить
7. Дмитрий Котов (rpgshnik) 89 30.05.17 06:47 Сейчас в теме
(6) Я вас дико поддерживаю!
10. Игорь Полосков (ipoloskov) 59 30.05.17 09:05 Сейчас в теме
Мне кажется, УникальныйИдентификатор - это не вполне случайное число, распределение будет совсем не равномерное.
Генератор случайных чисел
Brawler; VitaliyCeban; +2 Ответить
Оставьте свое сообщение