Перейти к публикации

Связанные поля


Рекомендованные сообщения

здесь уже просили пример по материалам, есть класс материал, класс профили.

профилю 1 соответствует столько-то материалов, другому еще столько-то ...

на примере SmDemo .. да в принципе все равно как ... сделайте как вам проще, может я чтото недопонял в этом вопросе ?!

Ссылка на сообщение
Поделиться на других сайтах


*SmarTeam Связанные поля*

На примере SmDemo и класса Material.

Поля:

-Material Type

-Material Standard

-------------------------------------------------------------------------------------------

У поля "Material Type" Events onExit Function: SelectMaterial

У поля "Material Standard" Events onEnter Function: ApplyUpdateMaterial

У поля "Material Standard" Events onExit Function: SelectMaterial

Все функции из файла SelectMaterial.bs его код:

Option Explicit

Function SelectMaterial(ApplHndl As Long,Sstr As String,RecLst1 As Long,RecLst2 As Long,RecLst3 As Long ) As Integer

  On Error GoTo error_ex



	  Dim SmSession As Object

	Dim GUIServices As Object



	Set SmSession = SCREXT_ObjectForInterface(ApplHndl) 

	Set GUIServices = SmSession.GetService("SmGUISrv.SmCommonGUI")	



Dim HomeDir As Variant

	  HomeDir =  SmSession.Config.HomeDirectory



	HomeDir = Shell("D:\Documents and Settings\Administrator\Desktop\Hook\Project1.exe Select " + Chr(34) + CSTR(GUIServices.ActiveViewWindow.SmView.ViewTitle) + Chr(34),1)



   	SelectMaterial = Err_None

Exit Function



error_ex : 

msgbox err.description

End Function

'================================================================================================

====================

Function ApplyUpdateMaterial(ApplHndl As Long,Sstr As String,RecLst1 As Long,RecLst2 As Long,RecLst3 As Long ) As Integer

  On Error GoTo error_ex



	  Dim SmSession As Object

	Dim GUIServices As Object



	Set SmSession = SCREXT_ObjectForInterface(ApplHndl) 

	Set GUIServices = SmSession.GetService("SmGUISrv.SmCommonGUI")	



Dim HomeDir As Variant

	  HomeDir =  SmSession.Config.HomeDirectory



	HomeDir = Shell("D:\Documents and Settings\Administrator\Desktop\Hook\Project1.exe Apply " + Chr(34) + CSTR(GUIServices.ActiveViewWindow.SmView.ViewTitle) + Chr(34),1)



   	ApplyUpdateMaterial = Err_None

Exit Function



error_ex : 

msgbox err.description

End Function

Этот код по событиям запускает программу и передает ей соответствующие параметры (см. код выше)

Теперь код самой программы:

FORM1.cpp

//---------------------------------------------------------------------------

#include <vcl.h>

#include <windows.h>

#include <iostream>

#include <stdio.h>

#pragma hdrstop



#include "Unit1.h"

//---------------------------------------------------------------------------

// ВНИМАНИЕ !!!															//

// ВЫ ЛИЧНО НЕСЕТЕ ОТВЕТСТВЕННОСТЬ ЗА ПОСЛЕДСТВИЯ ИСПОЛЬЗОВАНИЯ ЭТОГО КОДА.//

// АВТОР НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ ЗА ВОЗМОЖНЫЕ ОТРИЦАТЕЛЬНЫЕ ПОСЛЕДСТВИЯ   //

// ИСПОЛЬЗОВАНИЯ ЭТОГО КОДА В ЛЮБЫХ ПРОГРАММАХ ИЛИ САМОСТОЯТЕЛЬНО		  //

//--------------------------------------------------------------------------- 

#pragma package(smart_init)

#pragma resource "*.dfm"

AnsiString ConnectionString,ToDo;



void onCloseApplication( void );

void GettingArgcFunction( void );

BOOL CALLBACK GetMDIHanlde( HWND , LPARAM );

BOOL CALLBACK GetMDITGrabBarHanlde( HWND , LPARAM );

BOOL CALLBACK GetProfileConponentHanlde( HWND , LPARAM );

void SmarTeamComboBoxAddString( HWND , AnsiString , int );

void ClearSmarTeamComboBox( HWND );



TForm1		 *Form1;

HWND			MDIHandle, SmarTeamAppHandle,GrabBar;

AnsiString	  ActiveViewTitle,SQL,Atmp;

POINT		   GrabBarPosition;

char			n[256];

WINDOWPLACEMENT lpwndpl;

RECT			r,ComboBox1,ComboBox2;

POINT		   FromDB,TEMPPoint;

HWND			ProfileCardComponentHandle,TEMPHwnd;

LPARAM		  lParam;



using std::cout; using std::endl;

//---------------------------------------------------------------------------

void GettingArgcFunction( void )

{

   cout << "argc= " << _argc << endl;

  if(_argc > 1)

  {

   ToDo = _argv[_argc-2];

   ActiveViewTitle = _argv[_argc-1];

  }

	else

	 onCloseApplication();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)

{

ConnectionString = "Provider=OraOLEDB.Oracle.1;Password=smart1_test;Persist Security Info=True;User ID=smart1_test;Data Source=smart1";



	GettingArgcFunction();

	SmarTeamAppHandle	= GetForegroundWindow();

	MDIHandle			= NULL;

	EnumChildWindows(SmarTeamAppHandle,(WNDENUMPROC)GetMDIHanlde,0);

	if( !MDIHandle )onCloseApplication();



	GrabBar = NULL;

	EnumChildWindows(MDIHandle,(WNDENUMPROC)GetMDITGrabBarHanlde,0);

	if( !GrabBar )onCloseApplication();



	//=============================

	GetWindowRect(GrabBar,&r);

	GrabBarPosition.x = r.right;

	GrabBarPosition.y = r.top;

	//=============================

	SQL = "SELECT top_pos,left_pos,width,height FROM tdm_titles WHERE class_id = 438 AND screen_name = 'Attribute Profile Card' ";

	SQL = SQL + " AND caption = 'CN_MATERIAL_TYPE' AND lookup_id = 434";



	ComboBox1 = ActivateSQLRect(SQL);



	SQL = "SELECT top_pos,left_pos,width,height FROM tdm_titles WHERE class_id = 438 AND screen_name = 'Attribute Profile Card' ";

	SQL = SQL + " AND caption = 'CN_MATERIAL_STANDARD' AND lookup_id = 435";



	ComboBox2 = ActivateSQLRect(SQL);

			   if ( ToDo != "Apply" )

			   {

//------------GettingComboBox1Value

	FromDB.x = ComboBox1.left;

	FromDB.y = ComboBox1.top;

	ProfileCardComponentHandle = NULL;

	EnumChildWindows(MDIHandle,(WNDENUMPROC)GetProfileConponentHanlde,0);

	if( !ProfileCardComponentHandle )onCloseApplication();



	GetWindowRect(ProfileCardComponentHandle,&r);

	TEMPPoint.x = r.left+5;

	TEMPPoint.y = r.top+5;

	TEMPHwnd = WindowFromPoint(TEMPPoint);

	SendMessage(TEMPHwnd,WM_GETTEXT,256,(LPARAM)n);

//------------GettingComboBox1Value

/*================================================================



  Если выбран тип:						 То стандарт:

				  |-  Steel		==>				 AISI

				  |-  Lubricant	==>				 SAE

				  |-  Plastic	  ==>				 SAE,AISI

				  |-  Paper		==>				 AISI,ISO

				  |-  Aluminum	 ==>				 SAE,ISO

				  |-  Brass		==>				 ISO





  TN_MATERIAL_STANDARD (значения по умолчанию):

		-----------------------------------

		|  Description   |   Value_Order  |

		-----------------------------------

		|  SAE		   |   1			|

		-----------------------------------

		|  AISI		  |   2			|

		-----------------------------------

		|  ISO		   |   3			|

		-----------------------------------



==================================================================*/

	Atmp = n;



	FromDB.x = ComboBox2.left;

	FromDB.y = ComboBox2.top;

	ProfileCardComponentHandle = NULL;

	EnumChildWindows(MDIHandle,(WNDENUMPROC)GetProfileConponentHanlde,0);

	if( !ProfileCardComponentHandle )onCloseApplication();



	GetWindowRect(ProfileCardComponentHandle,&r);

	TEMPPoint.x = r.left+5;

	TEMPPoint.y = r.top+5;

	TEMPHwnd = WindowFromPoint(TEMPPoint);

	SendMessage(TEMPHwnd,WM_GETTEXT,256,(LPARAM)n);



		lParam = (LPARAM)(LPCTSTR)"";

		SendMessage(TEMPHwnd,WM_SETTEXT,0,lParam);

		SendMessage(TEMPHwnd,EM_SETMODIFY,(WPARAM)true,0);



	ClearSmarTeamComboBox(ProfileCardComponentHandle);



	  if ( Atmp == "Steel" )

	  {

	   SmarTeamComboBoxAddString(ProfileCardComponentHandle,"AISI",-1);

	  }

	  if ( Atmp == "Lubricant" )

	  {

	   SmarTeamComboBoxAddString(ProfileCardComponentHandle,"SAE",-1);

	  }

	  if ( Atmp == "Plastic" )

	  {

	   SmarTeamComboBoxAddString(ProfileCardComponentHandle,"SAE",-1);

	   SmarTeamComboBoxAddString(ProfileCardComponentHandle,"AISI",-1);

	  }

	  if ( Atmp == "Paper" )

	  {

	   SmarTeamComboBoxAddString(ProfileCardComponentHandle,"AISI",-1);

	   SmarTeamComboBoxAddString(ProfileCardComponentHandle,"ISO",-1);

	  }

	  if ( Atmp == "Aluminum" )

	  {

	   SmarTeamComboBoxAddString(ProfileCardComponentHandle,"SAE",-1);

	   SmarTeamComboBoxAddString(ProfileCardComponentHandle,"ISO",-1);

	  }

	  if ( Atmp == "Brass" )

	  {

	   SmarTeamComboBoxAddString(ProfileCardComponentHandle,"ISO",-1);

	  }

		  }else

		  {

//------------GettingComboBox2Value

	FromDB.x = ComboBox2.left;

	FromDB.y = ComboBox2.top;

	ProfileCardComponentHandle = NULL;

	EnumChildWindows(MDIHandle,(WNDENUMPROC)GetProfileConponentHanlde,0);

	if( !ProfileCardComponentHandle )onCloseApplication();



//------Aga

	SendMessage(ProfileCardComponentHandle,CB_GETLBTEXT,(WPARAM)SendMessage(ProfileCardComponentHandle,CB_GETCURSEL,0,0),(LPARAM)n);

	Atmp = n;

//------Aga



	GetWindowRect(ProfileCardComponentHandle,&r);

	TEMPPoint.x = r.left+5;

	TEMPPoint.y = r.top+5;

	TEMPHwnd = WindowFromPoint(TEMPPoint);

	SendMessage(TEMPHwnd,WM_SETTEXT,0,(LPARAM)n);

	SendMessage(TEMPHwnd,EM_SETMODIFY,(WPARAM)true,0);



//------ Rollback

	ClearSmarTeamComboBox(ProfileCardComponentHandle);

	lParam = (LPARAM)(LPCTSTR)"SAE";

	SendMessage(ProfileCardComponentHandle,CB_INSERTSTRING,(WPARAM)-1,lParam);

	SendMessage(ProfileCardComponentHandle,EM_SETMODIFY,(WPARAM)true,0);

	lParam = (LPARAM)(LPCTSTR)"AISI";

	SendMessage(ProfileCardComponentHandle,CB_INSERTSTRING,(WPARAM)-1,lParam);

	SendMessage(ProfileCardComponentHandle,EM_SETMODIFY,(WPARAM)true,0);

	lParam = (LPARAM)(LPCTSTR)"ISO";

	SendMessage(ProfileCardComponentHandle,CB_INSERTSTRING,(WPARAM)-1,lParam);

	SendMessage(ProfileCardComponentHandle,EM_SETMODIFY,(WPARAM)true,0);



int SelectedIndex;

	 if ( Atmp == "SAE" )SelectedIndex = 0;

	   if ( Atmp == "AISI" )SelectedIndex = 1;

		 if ( Atmp == "ISO" )SelectedIndex = 2;

	SendMessage(ProfileCardComponentHandle,CB_SETCURSEL,(WPARAM)SelectedIndex,0);

//------ Rollback

//------------GettingComboBox2Value

		  }

	onCloseApplication();

}

//---------------------------------------------------------------------------

void SmarTeamComboBoxAddString(HWND ComboBoxHandle , AnsiString ComboString , int Index)

{

	lParam = (LPARAM)(LPCTSTR)ComboString.c_str();

	SendMessage(ComboBoxHandle,CB_INSERTSTRING,(WPARAM)Index,lParam);

	SendMessage(ComboBoxHandle,EM_SETMODIFY,(WPARAM)true,0);

}

//---------------------------------------------------------------------------

void ClearSmarTeamComboBox(HWND ComboBoxHandle)

{

	if ( SendMessage(ComboBoxHandle,CB_GETCOUNT,0,0) == 0 ) return;

	SendMessage(ComboBoxHandle,CB_DELETESTRING,(WPARAM)0,0);

	SendMessage(ComboBoxHandle,EM_SETMODIFY,(WPARAM)true,0);

	ClearSmarTeamComboBox(ComboBoxHandle);

}

//---------------------------------------------------------------------------

bool __fastcall TForm1::ConnectToDB( void )

{

try{

	ADOConnection1->ConnectionString = ConnectionString;

	ADOConnection1->Connected = true;

	}catch(...){return false;}

	return true;

}

//---------------------------------------------------------------------------

RECT __fastcall TForm1::ActivateSQLRect( AnsiString SQLQuery )

{

	RECT temp_r;

	ConnectToDB();

	ADOQuery1->SQL->Clear();

	ADOQuery1->SQL->Add(SQLQuery);

	ADOQuery1->Active = true;

	temp_r.top = this->DBGrid1->Fields[0]->AsString.ToInt();

	temp_r.left = this->DBGrid1->Fields[1]->AsString.ToInt();

	temp_r.right = this->DBGrid1->Fields[2]->AsString.ToInt();

	temp_r.bottom = this->DBGrid1->Fields[3]->AsString.ToInt();

	DisconnectFromDB();

	return temp_r;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::DisconnectFromDB( void )

{

	ADOQuery1->Active = false;

	ADOQuery1->SQL->Clear();

	ADOConnection1->Connected = false;

}

//---------------------------------------------------------------------------

BOOL CALLBACK GetMDIHanlde(HWND hwnd, LPARAM lParam )

{

  if(GetClassName(hwnd,n,256))

  {

	  if(SendMessage(hwnd,WM_GETTEXT,256,(LPARAM)n)>0)

		if(AnsiString(n) == ActiveViewTitle)

		  if(!MDIHandle)

		  {

		  MDIHandle = hwnd;

		  return true;

		  }

  }

  return true;

}

//---------------------------------------------------------------------------

BOOL CALLBACK GetMDITGrabBarHanlde(HWND hwnd, LPARAM lParam )

{

  if( GetClassName(hwnd,n,256) )

	  if( AnsiString(n) == "TGrabBar" )

		  if( !GrabBar )

			   GrabBar = hwnd;



  return true;

}

//---------------------------------------------------------------------------

BOOL CALLBACK GetProfileConponentHanlde(HWND hwnd, LPARAM lParam )

{

  if( GetClassName(hwnd,n,256) )

  {

	WINDOWPLACEMENT lpwndpl;

	POINT temp_position;

	GetWindowPlacement(hwnd,&lpwndpl);

	 if(lpwndpl.showCmd == SW_SHOWNORMAL)

	  {

	  temp_position.x = lpwndpl.rcNormalPosition.left;

	  temp_position.y = lpwndpl.rcNormalPosition.top;

	  }

		if(lpwndpl.showCmd == SW_SHOWMAXIMIZED)

		{

		temp_position.x = lpwndpl.ptMaxPosition.x;

		temp_position.y = lpwndpl.ptMaxPosition.y;

		}

		  if(lpwndpl.showCmd == SW_SHOWMINIMIZED)

		  {

		  temp_position.x = lpwndpl.ptMinPosition.x;

		  temp_position.y = lpwndpl.ptMinPosition.y;

		  }



	  if ( temp_position.x == FromDB.x && temp_position.y == FromDB.y )

		if(!ProfileCardComponentHandle)

		 ProfileCardComponentHandle = hwnd;

  }

  return true;

}

//---------------------------------------------------------------------------

void onCloseApplication( void )

{ Application->Terminate(); }

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

		: TForm(Owner)

{}

//---------------------------------------------------------------------------

FORM1.h

//---------------------------------------------------------------------------



#ifndef Unit1H

#define Unit1H

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <ExtCtrls.hpp>

#include <ADODB.hpp>

#include <DB.hpp>

#include <DBGrids.hpp>

#include <Grids.hpp>

//---------------------------------------------------------------------------

class TForm1 : public TForm

{

__published:	// IDE-managed Components

		TDataSource *DataSource1;

		TADOConnection *ADOConnection1;

		TADOQuery *ADOQuery1;

		TDBGrid *DBGrid1;

		void __fastcall FormCreate(TObject *Sender);

//==============================================================

		bool __fastcall ConnectToDB( void );

		void __fastcall DisconnectFromDB( void );

		RECT __fastcall ActivateSQLRect( AnsiString SQLQuery);		

//==============================================================

private:	// User declarations

public:		// User declarations

		__fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

Всего то :)

Выкладываю вышеперечисленные исходники.

Компилятор BorlandC++ Builder 6

Перевод под язык Visual Studio (VB,C#,C++) без проблем, спрашивайте.

Ссылка на сообщение
Поделиться на других сайтах

Представляю радость в глазах конструкторов и технологов от

увиденного. Меня бы наши убили, если бы я им предложила подобное и еще добавила, что все это нужно откомпелировать.

Или может быть конструктора с технологами на других предприятиях

продвинутые пошли. Только не обижайтесь.

Выходит в любом случае работать будут программисты.

Только я не поняла, а зачем виды материалов напрямую в коде

перечисляются? Это не есть хорошо. Лучше брать из таблиц. Их

корректировать легче. И что такое 434, 435, 438? Тоже указание

напрямую. Насколько я поняла - это программа отображения уже

заложенных в базах SMARTEAM связей.

Ссылка на сообщение
Поделиться на других сайтах

to Елена

Начным с того что техноголи и конструкторы к этому отношения никакого не имеют.

Они работают с настроенным SmarTeam'ом а вот те кто настраивают должны это делать и не только это.

Хоть этот способ создания связанных полей мне не видится рациональным, я все равно написал его т.к. вопрос был сделать именно это.

Что касается 434, 435, 438 это идентификаторы бд смартим, и в этом примере я забил их как известные, их же можно получить автоматом , только вот код бы увеличился бы в два раза, да и для примера достаточно.

Покрайне мере для теж кто разбирается в SmarTeam'е все и так понятно.

В данном примере данные из БД нужны только лишь для того чтобы получить местоположение нужного поля на экране, для опреденения его Handle и все, никаких других данных от SmarTeam'а не нужно.

Вся логика закладывается на этапе настройки и создания программы которая и дает возможность использования связанных полей в SmarTeam Editore.

Что касается других подобных систем и вопросов типа да в ... есть связанные поля - в SmarTeam WEB Editore тоже есть да и обычном Editore тоже делают свои диалоги выбора на основе связанных полей, просто речь идет о голом SMARTEAM Editore.

Тем более этот код будет работать на любом смартиме, т.к. он не использует SMARTEAM API.

Еще вопросы :)

Ссылка на сообщение
Поделиться на других сайтах
  • 2 недели спустя...
  • 2 недели спустя...

2 green_fx

Изображение Feb 9 2006, 20:36

*SmarTeam Связанные поля*

Весь этот код, созданный почему-то до мессаджбоксов в сидаблплюсе, можно было реализовать двумя-тремя строчками - с использованием API

2 capitaine

Изображение Изображение Feb 22 2006, 12:27

2green_fx: ну и в чем я был не прав? ре :blink: ализуеццо-то все равно скриптами

Скриптами - по дефолту - должны реаливовываться только вызовы процедур, а сами процедуры - через динамические библиотеки и приложения (COM-объекты и т.п.).

Изменено пользователем Mikhaelle [CAD Etc.]
Ссылка на сообщение
Поделиться на других сайтах

2 Mikhaelle [CAD Etc.]

можно было реализовать двумя-тремя строчками - с использованием API

Каких таких API ? Пример пожалуйста!

Маленький комментарий SMARTEAM Editor под win32 - вперед!

Ссылка на сообщение
Поделиться на других сайтах
  • 2 недели спустя...

green_fx

Здравствуйте!

Не моли бы вы выложить вышеперечисленные исходники на языке VB.

Заранее благодарна за помощь. :smile:

Ссылка на сообщение
Поделиться на других сайтах

2 Angelika

Боюсь что нет.

Честно говоря сначала была попытка реализовать данный код используя чисто SMARTEAM'ый vb script, но к успеху это не привело т.к. в нем нет возможности корректной работы с адресами и памятью, например первые ошибки стали вылетать в отладчике, при попытке отработать вот эти строки:

имя_функции(0&, ByVal 0&)

EnumChildWindows MDIHandle, (WNDENUMPROC)GetProfileConponentHanlde,0  // С - код
да и просто времени не было с этим разбираться.
Ссылка на сообщение
Поделиться на других сайтах
  • 2 месяца спустя...

2All: буагагага

2Микхаель: все равно это будет скрипт. наличие ЛЮБОГО скрипта накладывает ограничения. Арсеналу, кстати, привет от Криогенмаша ))

Ссылка на сообщение
Поделиться на других сайтах

To <A href="http://fsapr2000.ru/index.php?showuser=1895">capitaine

Сообщение #31

Изображение

Ага, но чем меньше я суну в скрипт, и чем, соответственно, больше - во внешнее приложение/библиотеку, тем удобнее. Кстати, отспецифицировав вызовы внешних процедур, я получаю замечательную возможность использовать эти процедуры в любых скриптах, не повторяя код.

Наилучшим образом выглядели бы скрипты, содержащие только вызовы процедур.

Под процедурами я понимаю код, который часто встречался бы в различных скриптах, если бы он не был выделен во внешнее приложение/библиотеку.

WEB-интерфейс - отдельный вопрос...

Ссылка на сообщение
Поделиться на других сайтах

Микхаэль, я уже слышал ваши слова на нашей встрече в начале мая у вас. и совершенно с ними не спорю.

а основная вредность большого количества скриптов заключается отнюдь не в некотором замедлении работы смартима...

вот вредности, которые я вижу:

- большое количество скриптов накладывает ограничения на работу некоторых модулей СТ (веб-интерфейс, ворк-флоу). более того, скрипты в определенных модулях могут работать чуть не так, как это планировалось и работает в Едиторе

- большое количество скриптов затрудняет внесение изменений в них (дело даже не в повторяющемся коде), запутывает модель данных

- исходя из второго пункта... если увольняется один из программистов, который писал скрипты для СТ, то новому программисту понадобится знаааачительное время, чтобы въехать в наработки. причем, чем больше скриптов, чем запутаннее вызовы из них функций, тем времени на разбирательство больше. более того, новый программист далеко не всегда будет переделывать старые скрипты, а будет пытаться использовать существующий код as-is, в результате чего путаница будет офигительная, а результаты работы скриптов новых и старых будут мало предсказуемыми.

последний пункт в общем виде не относится к СТ, а относится к любой системе, которую сильно запрограммировали (прости мне этот ламерский термин :)...

Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете опубликовать сообщение сейчас, а зарегистрироваться позже. Если у вас есть аккаунт, войдите в него для написания от своего имени.
Примечание: вашему сообщению потребуется утверждение модератора, прежде чем оно станет доступным.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.




×
×
  • Создать...