问:
Asp.net core with linux docker container
For a asp.net core project template in VS 2017, there are docker-compose.ci.build.yml:

```<code>version: '3'

services:
  ci-build:
    image: microsoft/aspnetcore-build:1.0-2.0
    volumes:
      - .:/src
    working_dir: /src
    command: /bin/bash -c "dotnet restore ./WebAppCoreDockerTest.sln && dotnet publish ./WebAppCoreDockerTest.sln -c Release -o ./obj/Docker/publish"
</code>```

docker-compose.yml:

```<code>version: '3'

services:
  webappcoredockertest:
    image: webappcoredockertest
    ports:
      - 8080:80
    build:
      context: ./WebAppCoreDockerTest
      dockerfile: Dockerfile
</code>```

and Dockerfile:

```<code>FROM microsoft/aspnetcore:2.0
ARG source
WORKDIR /app
EXPOSE 80
RUN echo "Oh dang look at that $source"
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "WebAppCoreDockerTest.dll"]
</code>```

The Dockerfile uses the files in obj/Docker/publish (copied to container) if source argument is null and docker-compose.ci.build.yml puhlishs project to obj/Docker/publish, I assume they are related.

So the question is How to use them together? (docker-compose.ci.build.yml publishes files to obj/Docker/publish and Dockerfile use published files)

答:
The docker-compose.ci.build.yml file is for building the project, as you mentioned.  It uses the aspnetcore-build base image which is much heftier than the aspnetcore image used by the Dockerfile.  The Dockerfile gets used by the build section of the docker-compose.yml file.

Everything works together with these two steps:

docker-compose -f docker-compose.ci.build.yml run ci-build

docker-compose up --build

The -f option in the first command allows you to specify a compose file other than the default docker-compose.yml.

Body:
For a asp.net core project template in VS 2017, there are docker-compose.ci.build.yml:

version: '3'

services:
  ci-build:
    image: microsoft/aspnetcore-build:1.0-2.0
    volumes:
      - .:/src
    working_dir: /src
    command: /bin/bash -c "dotnet restore ./WebAppCoreDockerTest.sln && dotnet publish ./WebAppCoreDockerTest.sln -c Release -o ./obj/Docker/publish"

docker-compose.yml:

version: '3'

services:
  webappcoredockertest:
    image: webappcoredockertest
    ports:
      - 8080:80
    build:
      context: ./WebAppCoreDockerTest
      dockerfile: Dockerfile

and Dockerfile:

FROM microsoft/aspnetcore:2.0
ARG source
WORKDIR /app
EXPOSE 80
RUN echo "Oh dang look at that $source"
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "WebAppCoreDockerTest.dll"]

The Dockerfile uses the files in obj/Docker/publish (copied to container) if source argument is null and docker-compose.ci.build.yml puhlishs project to obj/Docker/publish, I assume they are related.

So the question is How to use them together? (docker-compose.ci.build.yml publishes files to obj/Docker/publish and Dockerfile use published files)


来源: stackexchange

问:
Trigger the phone function by clicking the number once in the HTML
I add xxx in the HTML.

I insert the HTML into the Xcode and use WKWebView to load the HTML.

Then run the Demo on my iPhone.

I must long press the xxx number to trigger An alert displayed modally for the app. The first button of the alert shows the text "Call XXX".

If I press the "Call XXX" button, then the iPhone will call.

.

In my opinion, the long press is not a friendly way to the user.

Is there a way to trigger the phone function by clicking the number once in the HTML.

One more thing, I will insert the HTML into the Android App.

In Android App, How to trigger the phone call by clicking the number.

答:
You should Override shouldOverrideUrlLoading method in your Webview Client and do whatever you want with that url.

```<code>    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
    //do something here
    return true;
   }
</code>```

ContentLicense: CC BY-SA 3.0

Body:
You should Override shouldOverrideUrlLoading method in your Webview Client and do whatever you want with that url.

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
    //do something here
    return true;
   }


问:
i keep getting this error at the first line of my configuration file in spring project
project structure

the only suggested solution for this error i get is to configure build path. I consider it is already everything at its place. please tell me the problem.

The error:

Multiple markers at this line
      - The type org.springframework.http.HttpStatus cannot be resolved. It is indirectly referenced from
       required .class files
      - The type org.springframework.web.method.support.HandlerMethodReturnValueHandler cannot be resolved.
       It is indirectly referenced from required .class files

i'm working on spring tool suite. here is my configuration file:

```<code>package com.health.config;
import java.io.IOException;

import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import com.health.dao.DAO;
import com.health.dao.DAOImpl;

@Configuration
@ComponentScan(basePackages="com.health")
@EnableWebMvc
@Component
public class AppConfig extends WebMvcConfigurerAdapter{

     @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
         registry.addResourceHandler("/resources/**").addResourceLocations("resources/");
        }

    @Bean
    public ViewResolver getViewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Bean
    public DataSource getDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/contactdb");
        dataSource.setUsername("root");
        dataSource.setPassword("welkinfort");
        return dataSource;
    }

    @Bean
    public DAO getDAO() {
        return new DAOImpl(getDataSource());
    }
}
</code>```

here is my pom.xml:

```<code><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.health</groupId>
<artifactId>healthcare</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>healthcare Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.38</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.10</version>
    </dependency>

    <!-- jackson-annotations -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.8.1</version>
    </dependency>
    <!-- jackson-core -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.8.1</version>
    </dependency>
    <!-- jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.1</version>
    </dependency>

    <dependency>                                    <!-- file-upload -->
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.1</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>

    <dependency>                                <!-- spring-webmvc -->
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.1.8.RELEASE</version>
    </dependency>

    <dependency>                                <!-- spring-jdbc -->
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.2.5.RELEASE</version>
    </dependency>

    <dependency>                        <!--tomcat7-maven-plugin -->
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-catalina</artifactId>
        <version>7.0.47</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>                                    <!-- jstl -->
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.1.2</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
<build>
    <finalName>healthcare</finalName>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <fork>true</fork>
                <executable>C:\Program Files\Java\jdk1.8.0_144\bin\javac</executable>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
        </plugin>
    </plugins>
</build>
</code>```

答:
You are missing spring-web dependency. The org.springframework.http.HttpStatus is  part of spring-web jar. Add this to your pom.xml:</p>

```<code><dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.2.5.RELEASE</version>
</dependency>
</code>```

Body:
project structure

the only suggested solution for this error i get is to configure build path. I consider it is already everything at its place. please tell me the problem.

The error:

Multiple markers at this line
      - The type org.springframework.http.HttpStatus cannot be resolved. It is indirectly referenced from
       required .class files
      - The type org.springframework.web.method.support.HandlerMethodReturnValueHandler cannot be resolved.
       It is indirectly referenced from required .class files

i'm working on spring tool suite. here is my configuration file:

package com.health.config;
import java.io.IOException;

import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import com.health.dao.DAO;
import com.health.dao.DAOImpl;

@Configuration
@ComponentScan(basePackages="com.health")
@EnableWebMvc
@Component
public class AppConfig extends WebMvcConfigurerAdapter{

     @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
         registry.addResourceHandler("/resources/**").addResourceLocations("resources/");
        }

    @Bean
    public ViewResolver getViewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Bean
    public DataSource getDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/contactdb");
        dataSource.setUsername("root");
        dataSource.setPassword("welkinfort");
        return dataSource;
    }

    @Bean
    public DAO getDAO() {
        return new DAOImpl(getDataSource());
    }
}

here is my pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.health</groupId>
<artifactId>healthcare</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>healthcare Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.38</version>
    </dependency>

    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.10</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.8.1</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.8.1</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.1</version>
    </dependency>

    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.1</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.1.8.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.2.5.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-catalina</artifactId>
        <version>7.0.47</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.1.2</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
<build>
    <finalName>healthcare</finalName>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <fork>true</fork>
                <executable>C:\Program Files\Java\jdk1.8.0_144\bin\javac</executable>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
        </plugin>
    </plugins>
</build>

Body:
You are missing spring-web dependency. The org.springframework.http.HttpStatus is  part of spring-web jar. Add this to your pom.xml:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.2.5.RELEASE</version>
</dependency>


问:
Should I use Log file or DB to track impression?
I have a picture (similar to an ad) in an iframe that will be placed in multiple sites.  Should I use the server log file to find out the impression? or should I use DB to keep track of each impression?

which way is faster and can handle large volume of traffic?  thanks

答:
The answer for this question really depends on what kind of database you are using, and how busy the web servers disk and the database really are in your deployment environment;

If you cat a log entry to a file each time an impression is done this is pretty fast. You can daily move this file to a new file and send it to some back-end system to process it and you would most likely never loose an entry (unless you encounter a disk crash)

A regular mysql database with a table entry might be overkill for this unless you want to use the same table for doing queries on the data. It would probably also scale well, but you could end up with a lot of entries here if you have lots of traffic.

Using a nosql database for this could be a good match, and this would probably scale it up to scaling like twitter - though most sites aren't like Twitter so it is probably overkill for your needs :)

If you have a regular website you can probably get away with doing it the first way as it is simple. If it does not, you haven't spent a lot of time on it.

ContentLicense: CC BY-SA 2.5


问:
Downloading directory from FTP server
I am developing FTP client by RAD Studio (IdFTP). How I can dowload directory from server?
Delphi or C++. Thanks.

答:
It is necessary to add the condition:

Else if ((IdFTP.DirectoryListing[I].ItemType = ditDirectory) and
  (Length(IdFTP.DirectoryListing[I].FileName) > 2)) then

to avoid ".." as the directory name

Title: Downloading directory from FTP server


问:
Key difference between PID and LQI integral terms
I am working on control theory implementation on quadcopters. So far I have empirically implemented a PID and an LQI (Linear Quadratic Integral) controllers and tested them. I got a MUCH robust performance from LQI in terms of noise and disturbance rejection, and model uncertainties (click here for detailed analysis).

However, I understand that the PID control output u is:

u(s) = [Kp + Ki/s + Kd*s]*e(s)

and the LQI output is:

u(s) = -Kx * x(s) - Ki * xi(s)

My question is mainly about the integral term in each controller. Both of the controllers integrate the error e and have a zero at the origin. How is the LQI controller is better (more robust) that the PID one?

答:
This is not always true though in general it is practically true since PID control tuning is a local optimization problem compared to the state feedback+integrator design.

What the difference is that in the LQI control you are using the state information to control the system and driving the steady state error quicker with an extra integrator.

In PID case however you are using the output of the system which (assuming observability and controllability) cannot immediately have all the information. Imagine there are two states a fast one and a rather slow one and you are only observing a strange combination of them encoded in your C matrix. PID works on that observed quantity whereas LQI works with both states simultaneously.


问:
I am trying to run my app in background . But service Class is not working in background
It is an app that calculates some data and I want it to work in background if the app is closed. Here is my code

Here is the main activity.

```<code>  public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    RadioButton selectedRdb;
    RadioGroup gender;
    EditText drinkingTime;
    EditText bodyweight;
    EditText volume;

    EditText size;
    Intent counterIntent;

    String genderOfThePerson;
    Button start;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        gender = (RadioGroup) findViewById(R.id.genderRbGroup);

        drinkingTime = (EditText) findViewById(R.id.juontiAika);
        bodyweight = (EditText) findViewById(R.id.kehonPaino);

        volume = (EditText)findViewById(R.id.vahvuus);
        size = (EditText)findViewById(R.id.koko);
        start = (Button)findViewById(R.id.startBtn);
        counterIntent = new Intent(this, Counter.class);
    }

    public void startCounter(View view) {
        if(gender.getCheckedRadioButtonId()==-1)
        {
            Toast.makeText(getApplicationContext(), "Please select Gender", Toast.LENGTH_SHORT).show();
        }
        else{
            int selectedId = gender.getCheckedRadioButtonId();
            selectedRdb = (RadioButton)findViewById(selectedId);
            if(selectedRdb.getText().toString().equalsIgnoreCase("male")){
                genderOfThePerson = "male";
            }
            else if(selectedRdb.getText().toString().equalsIgnoreCase("female")){
                genderOfThePerson = "female";
            }

        }

        int bodyWeight = Integer.parseInt(bodyweight.getText().toString());

        double drinkSize = Double.parseDouble(size.getText().toString());
        drinkSize = drinkSize/10;

        double drinkVolume = Double.parseDouble(volume.getText().toString());
        double drinkingtime = Double.parseDouble(drinkingTime.getText().toString());

        //muutetaan juomisaika tunneiksi
        drinkingtime = drinkingtime / 60;

        counterIntent.putExtra("juomankoko", drinkSize);
        counterIntent.putExtra("juomanvahvuus", drinkVolume);
        counterIntent.putExtra("sukupuoli", genderOfThePerson);
        counterIntent.putExtra("kehonpaino", bodyWeight);

        counterIntent.putExtra("juontiaika", drinkingtime);

        startActivity(counterIntent);

    }

}
</code>```

Here is Counter Activity :-

```<code>    package com.mypackage.henri.beerdrinkreminder;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import android.content.IntentFilter;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.mypackage.henri.beerdrinkreminder.Un.MainActivity;

import java.text.DecimalFormat;

public class Counter extends AppCompatActivity {

    Intent mainactivityIntent;
    Intent serviceIntent;
    TextView promilletTxt;
    TextView kanniAika;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_counter);

        mainactivityIntent  = new Intent(this, MainActivity.class);

        promilletTxt = (TextView)findViewById(R.id.bacTxt);
        kanniAika = (TextView)findViewById(R.id.känniAika);

        Button drinkButton = (Button)findViewById(R.id.drinkBtn);
        Button lopetaBtn = (Button)findViewById(R.id.stopBtn);
        Intent i = getIntent();

        //GETS THE USER INFO VARIABLES FROM INTENT AND SENDS THE FORWARD TO THE SERVICE
        serviceIntent = new Intent(Counter.this, CounterService.class);

        serviceIntent.putExtra("juomankoko", i.getDoubleExtra("juomankoko", 0));
        serviceIntent.putExtra("juomanvahvuus", i.getDoubleExtra("juomanvahvuus", 0));
        serviceIntent.putExtra("sukupuoli", i.getStringExtra("sukupuoli"));
        serviceIntent.putExtra("kehonpaino", i.getIntExtra("kehonpaino", 0));
        serviceIntent.putExtra("juontiaika", i.getDoubleExtra("juontiaika",0));

        startService(serviceIntent);
        registerReceiver(broadcastReceiver, new IntentFilter(CounterService.BROADCAST_ACTION));

        drinkButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //THIS IS FOR ADDING ANOTHER DRINK WHEN THE CALCULATOR IS ALREADY RUNNING
                AlertDialog.Builder builder = new AlertDialog.Builder(Counter.this);
                View dView = getLayoutInflater().inflate(R.layout.drinkdialog,null);
                final EditText dSize = (EditText)dView.findViewById(R.id.drinkSize);
                final EditText dTime = (EditText)dView.findViewById(R.id.drinkingTime);
                final EditText dStrenght = (EditText)dView.findViewById(R.id.juomanVahvuus);
                Button submitBtn = (Button)dView.findViewById(R.id.drinkBtn);

                builder.setView(dView);
                final AlertDialog dialog = builder.create();

                dialog.show();

                submitBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if(dSize.getText().toString().isEmpty()){
                            Toast.makeText(Counter.this, "Add the size of the drink", Toast.LENGTH_SHORT).show();
                        }
                        else if(dTime.getText().toString().isEmpty()){
                            Toast.makeText(Counter.this, "Add the drinking time", Toast.LENGTH_SHORT).show();
                        }
                        else{
                            double juomankoko = Double.parseDouble(dSize.getText().toString());
                            double juontiaika = Double.parseDouble(dTime.getText().toString());
                            double juomanvahvuus = Double.parseDouble(dStrenght.getText().toString());

                            serviceIntent.putExtra("juomankoko", juomankoko);
                            serviceIntent.putExtra("juontiaika", juontiaika);
                            serviceIntent.putExtra("juomanvahvuus", juomanvahvuus);

                            //THIS IS ID IS FOR CHECKING WHERE DID THE START REQUEST COME FROM. IF THE ID IS NOT 0,
                            // THEN THE SERVICE HAS ALREADY STARTED ATLEAST ONCE AND THE ALCOHOL CALCULATOR HAS BEEN CREATED ALREADY.
                            serviceIntent.putExtra("id", 123);

                            //STARTS SERVICE AGAIN
                            startService(serviceIntent);
                            dialog.cancel();

                        }
                    }
                });

            }
        });

        //THIS BUTTON IS FOR CANCELLING THE CALCULATIONS
        lopetaBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                AlertDialog.Builder builder = new AlertDialog.Builder(Counter.this);
                View dView = getLayoutInflater().inflate(R.layout.lopetusdialogi,null);

                TextView bac = (TextView) dView.findViewById(R.id.bac);
                TextView aikaaPäisn = (TextView)dView.findViewById(R.id.aikaaPäisn);
                /*bac.setText(alcCal.calculateCurrentBac(palamisVauhtiSekunissa) + "%");

                double aika = (alcCal.getGrammat() / palamisVauhtiSekunissa) / 3600;
                int tunnit = (int)Math.floor(aika);
                int minuutit = (int)Math.floor((aika - tunnit) * 60);

                aikaaPäisn.setText(tunnit + " hours " + minuutit + " minutes");
                */
                builder.setView(dView);
                final AlertDialog dialog = builder.create();

                dialog.show();

                Button dialoginLopetus = (Button)dView.findViewById(R.id.dialoginLopetus);

                dialoginLopetus.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        startActivity(mainactivityIntent);
                    }
                });

            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();

        startService(serviceIntent);
        registerReceiver(broadcastReceiver, new IntentFilter(CounterService.BROADCAST_ACTION));
    }

    @Override
    protected void onStop() {
        super.onStop();

        unregisterReceiver(broadcastReceiver);
        startService(new Intent(this, CounterService.class));
     //   registerReceiver(broadcastReceiver, new IntentFilter(CounterService.BROADCAST_ACTION));

    }

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            updateUI(intent);
        }
    };

    private void updateUI(Intent intent) {

        //THIS METHOD GETS THE CALCULATED ALCOHOL LEVEL AND TIME FROM THE PARAMETER INTENT AND DISPLAYS IT IN THE TEXTVIEWS
        double promillet = intent.getDoubleExtra("promillet", 0.0);
        double aikaPäisn = intent.getDoubleExtra("aika", 0.0);
        double grammat = intent.getDoubleExtra("grammat", 0.0);

        DecimalFormat df = new DecimalFormat("0.000");

        int tunnit = (int)Math.floor(aikaPäisn);
        int minuutit = (int)Math.floor((aikaPäisn - tunnit) * 60);

        promilletTxt.setText(df.format(promillet) + " %");
        kanniAika.setText(tunnit + " hours " + minuutit + " minutes");

    }
}
</code>```

I am trying to run this app when I destroy all activity.
Here is my Counter Service

```<code>package com.mypackage.henri.beerdrinkreminder;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class CounterService extends Service {

    private static final String TAG = "CounterService";
    private Intent intent;
    public static final String BROADCAST_ACTION = "com.mypackage.henri.beerdrinkreminder.CounterService";

    private Handler handler = new Handler();

    AlcoholCalc alcCalc;

    //VARIABLES FOR THE CALCULATIONS
    double palamisVauhtiSekunissa;
    double promillet;
    private int aloitusLukema = 0;

    @Override
    public void onCreate() {
        super.onCreate();
        intent = new Intent(BROADCAST_ACTION);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
      //  intent = new Intent(BROADCAST_ACTION);
        aloitusLukema++;

        //THIS IS FOR CHECKING IF THE SERVICE IS STARTED FOR THE FIRST TIME. IF IT IS, THEN WE CONSTRUCT THE ALCOHOL CALCULATOR.

        if(aloitusLukema == 1){

            int kehonpaino = intent.getIntExtra("kehonpaino", 0);
            Toast.makeText(getApplicationContext(),""+kehonpaino,Toast.LENGTH_SHORT).show();

            double juomanKoko = intent.getDoubleExtra("juomankoko", 0.0);

            double juomanVahvuus = intent.getDoubleExtra("juomanvahvuus", 0.0);

            double juontiaika = (intent.getDoubleExtra("juontiaika", 0.0));

            String sukupuoli = intent.getStringExtra("sukupuoli");

            alcCalc = new AlcoholCalc(sukupuoli,
                    kehonpaino,
                    juomanVahvuus,
                    juontiaika,
                    juomanKoko);
            double palamisvauhtiTunnissa = kehonpaino / 10;

            palamisVauhtiSekunissa = palamisvauhtiTunnissa / 3600;

        }
       /*
        //THIS SECTION IS DONE IF THE USER PRESSES THE DRINK-BUTTON IN COUNTER ACVITIVY AND ADDS ANOTHER DRINK.
        else if (intent.getIntExtra("id", 0) != 0){

            double juomanKoko = intent.getDoubleExtra("juomankoko", 0.0);

            double juomanVahvuus = intent.getDoubleExtra("juomanvahvuus", 0.0);

            double juontiaika = (intent.getDoubleExtra("juontiaika", 0.0));

            alcCalc.drinkABeer(juomanKoko/10, juontiaika, juomanVahvuus);

        }
        */

        handler.removeCallbacks(sendUpdatesToUI);
        handler.postDelayed(sendUpdatesToUI, 1000);

        return START_STICKY;

    }

    private Runnable sendUpdatesToUI = new Runnable() {
        public void run() {
            AlcCalculations();
            handler.postDelayed(this, 1000);
        }
    };

    private void AlcCalculations() {

        //THIS IS FOR CALCULATING THE ALCOHOL LEVEL
        promillet = alcCalc.calculateCurrentBac(palamisVauhtiSekunissa);

        double aikaTunteina = (alcCalc.getGrammat() / palamisVauhtiSekunissa) / 3600;

        intent.putExtra("aika", aikaTunteina);
        intent.putExtra("promillet", promillet);
        intent.putExtra("grammat", alcCalc.getGrammat());
        sendBroadcast(intent);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        handler.removeCallbacks(sendUpdatesToUI);

    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}
</code>```

The app runs well in OnPause State. When I close the app it shows some error message :-

```<code>11-14 04:59:15.149 3539-3539/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 java.lang.RuntimeException: Unable to start service com.mypackage.henri.beerdrinkreminder.CounterService@536765c8 with null: java.lang.NullPointerException
                                                     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2507)
                                                     at android.app.ActivityThread.access$1900(ActivityThread.java:130)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1292)
                                                     at android.os.Handler.dispatchMessage(Handler.java:99)
                                                     at android.os.Looper.loop(Looper.java:137)
                                                     at android.app.ActivityThread.main(ActivityThread.java:4745)
                                                     at java.lang.reflect.Method.invokeNative(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:511)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                                                     at dalvik.system.NativeStart.main(Native Method)
                                                  Caused by: java.lang.NullPointerException
                                                     at com.mypackage.henri.beerdrinkreminder.CounterService.onStartCommand(CounterService.java:46)
                                                     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2490)
                                                     at android.app.ActivityThread.access$1900(ActivityThread.java:130)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1292)
                                                     at android.os.Handler.dispatchMessage(Handler.java:99)
                                                     at android.os.Looper.loop(Looper.java:137)
                                                     at android.app.ActivityThread.main(ActivityThread.java:4745)
                                                     at java.lang.reflect.Method.invokeNative(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:511)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                                                     at dalvik.system.NativeStart.main(Native Method)
11-14 04:59:17.345 3539-3539/? I/Process: Sending signal. PID: 3539 SIG: 9
</code>```

答:
remove Toast from your service

```<code>Toast.makeText(getApplicationContext(),""+kehonpaino,Toast.LENGTH_SHORT).show();
</code>```

An Service has a few limitations:
It can't interact directly with your user interface.

Body:
It is an app that calculates some data and I want it to work in background if the app is closed. Here is my code

Here is the main activity.

  public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    RadioButton selectedRdb;
    RadioGroup gender;
    EditText drinkingTime;
    EditText bodyweight;
    EditText volume;

    EditText size;
    Intent counterIntent;

    String genderOfThePerson;
    Button start;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        gender = (RadioGroup) findViewById(R.id.genderRbGroup);

        drinkingTime = (EditText) findViewById(R.id.juontiAika);
        bodyweight = (EditText) findViewById(R.id.kehonPaino);

        volume = (EditText)findViewById(R.id.vahvuus);
        size = (EditText)findViewById(R.id.koko);
        start = (Button)findViewById(R.id.startBtn);
        counterIntent = new Intent(this, Counter.class);
    }

    public void startCounter(View view) {
        if(gender.getCheckedRadioButtonId()==-1)
        {
            Toast.makeText(getApplicationContext(), "Please select Gender", Toast.LENGTH_SHORT).show();
        }
        else{
            int selectedId = gender.getCheckedRadioButtonId();
            selectedRdb = (RadioButton)findViewById(selectedId);
            if(selectedRdb.getText().toString().equalsIgnoreCase("male")){
                genderOfThePerson = "male";
            }
            else if(selectedRdb.getText().toString().equalsIgnoreCase("female")){
                genderOfThePerson = "female";
            }

        }

        int bodyWeight = Integer.parseInt(bodyweight.getText().toString());

        double drinkSize = Double.parseDouble(size.getText().toString());
        drinkSize = drinkSize/10;

        double drinkVolume = Double.parseDouble(volume.getText().toString());
        double drinkingtime = Double.parseDouble(drinkingTime.getText().toString());

        //muutetaan juomisaika tunneiksi
        drinkingtime = drinkingtime / 60;

        counterIntent.putExtra("juomankoko", drinkSize);
        counterIntent.putExtra("juomanvahvuus", drinkVolume);
        counterIntent.putExtra("sukupuoli", genderOfThePerson);
        counterIntent.putExtra("kehonpaino", bodyWeight);

        counterIntent.putExtra("juontiaika", drinkingtime);

        startActivity(counterIntent);

    }

}

Here is Counter Activity :-

    package com.mypackage.henri.beerdrinkreminder;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import android.content.IntentFilter;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.mypackage.henri.beerdrinkreminder.Un.MainActivity;

import java.text.DecimalFormat;

public class Counter extends AppCompatActivity {

    Intent mainactivityIntent;
    Intent serviceIntent;
    TextView promilletTxt;
    TextView kanniAika;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_counter);

        mainactivityIntent  = new Intent(this, MainActivity.class);

        promilletTxt = (TextView)findViewById(R.id.bacTxt);
        kanniAika = (TextView)findViewById(R.id.känniAika);

        Button drinkButton = (Button)findViewById(R.id.drinkBtn);
        Button lopetaBtn = (Button)findViewById(R.id.stopBtn);
        Intent i = getIntent();

        //GETS THE USER INFO VARIABLES FROM INTENT AND SENDS THE FORWARD TO THE SERVICE
        serviceIntent = new Intent(Counter.this, CounterService.class);

        serviceIntent.putExtra("juomankoko", i.getDoubleExtra("juomankoko", 0));
        serviceIntent.putExtra("juomanvahvuus", i.getDoubleExtra("juomanvahvuus", 0));
        serviceIntent.putExtra("sukupuoli", i.getStringExtra("sukupuoli"));
        serviceIntent.putExtra("kehonpaino", i.getIntExtra("kehonpaino", 0));
        serviceIntent.putExtra("juontiaika", i.getDoubleExtra("juontiaika",0));

        startService(serviceIntent);
        registerReceiver(broadcastReceiver, new IntentFilter(CounterService.BROADCAST_ACTION));

        drinkButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //THIS IS FOR ADDING ANOTHER DRINK WHEN THE CALCULATOR IS ALREADY RUNNING
                AlertDialog.Builder builder = new AlertDialog.Builder(Counter.this);
                View dView = getLayoutInflater().inflate(R.layout.drinkdialog,null);
                final EditText dSize = (EditText)dView.findViewById(R.id.drinkSize);
                final EditText dTime = (EditText)dView.findViewById(R.id.drinkingTime);
                final EditText dStrenght = (EditText)dView.findViewById(R.id.juomanVahvuus);
                Button submitBtn = (Button)dView.findViewById(R.id.drinkBtn);

                builder.setView(dView);
                final AlertDialog dialog = builder.create();

                dialog.show();

                submitBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if(dSize.getText().toString().isEmpty()){
                            Toast.makeText(Counter.this, "Add the size of the drink", Toast.LENGTH_SHORT).show();
                        }
                        else if(dTime.getText().toString().isEmpty()){
                            Toast.makeText(Counter.this, "Add the drinking time", Toast.LENGTH_SHORT).show();
                        }
                        else{
                            double juomankoko = Double.parseDouble(dSize.getText().toString());
                            double juontiaika = Double.parseDouble(dTime.getText().toString());
                            double juomanvahvuus = Double.parseDouble(dStrenght.getText().toString());

                            serviceIntent.putExtra("juomankoko", juomankoko);
                            serviceIntent.putExtra("juontiaika", juontiaika);
                            serviceIntent.putExtra("juomanvahvuus", juomanvahvuus);

                            //THIS IS ID IS FOR CHECKING WHERE DID THE START REQUEST COME FROM. IF THE ID IS NOT 0,
                            // THEN THE SERVICE HAS ALREADY STARTED ATLEAST ONCE AND THE ALCOHOL CALCULATOR HAS BEEN CREATED ALREADY.
                            serviceIntent.putExtra("id", 123);

                            //STARTS SERVICE AGAIN
                            startService(serviceIntent);
                            dialog.cancel();

                        }
                    }
                });

            }
        });

        //THIS BUTTON IS FOR CANCELLING THE CALCULATIONS
        lopetaBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                AlertDialog.Builder builder = new AlertDialog.Builder(Counter.this);
                View dView = getLayoutInflater().inflate(R.layout.lopetusdialogi,null);

                TextView bac = (TextView) dView.findViewById(R.id.bac);
                TextView aikaaPäisn = (TextView)dView.findViewById(R.id.aikaaPäisn);
                /*bac.setText(alcCal.calculateCurrentBac(palamisVauhtiSekunissa) + "%");

                double aika = (alcCal.getGrammat() / palamisVauhtiSekunissa) / 3600;
                int tunnit = (int)Math.floor(aika);
                int minuutit = (int)Math.floor((aika - tunnit) * 60);

                aikaaPäisn.setText(tunnit + " hours " + minuutit + " minutes");
                */
                builder.setView(dView);
                final AlertDialog dialog = builder.create();

                dialog.show();

                Button dialoginLopetus = (Button)dView.findViewById(R.id.dialoginLopetus);

                dialoginLopetus.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        startActivity(mainactivityIntent);
                    }
                });

            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();

        startService(serviceIntent);
        registerReceiver(broadcastReceiver, new IntentFilter(CounterService.BROADCAST_ACTION));
    }

    @Override
    protected void onStop() {
        super.onStop();

        unregisterReceiver(broadcastReceiver);
        startService(new Intent(this, CounterService.class));
     //   registerReceiver(broadcastReceiver, new IntentFilter(CounterService.BROADCAST_ACTION));

    }

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            updateUI(intent);
        }
    };

    private void updateUI(Intent intent) {

        //THIS METHOD GETS THE CALCULATED ALCOHOL LEVEL AND TIME FROM THE PARAMETER INTENT AND DISPLAYS IT IN THE TEXTVIEWS
        double promillet = intent.getDoubleExtra("promillet", 0.0);
        double aikaPäisn = intent.getDoubleExtra("aika", 0.0);
        double grammat = intent.getDoubleExtra("grammat", 0.0);

        DecimalFormat df = new DecimalFormat("0.000");

        int tunnit = (int)Math.floor(aikaPäisn);
        int minuutit = (int)Math.floor((aikaPäisn - tunnit) * 60);

        promilletTxt.setText(df.format(promillet) + " %");
        kanniAika.setText(tunnit + " hours " + minuutit + " minutes");

    }
}

I am trying to run this app when I destroy all activity.
Here is my Counter Service

package com.mypackage.henri.beerdrinkreminder;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class CounterService extends Service {

    private static final String TAG = "CounterService";
    private Intent intent;
    public static final String BROADCAST_ACTION = "com.mypackage.henri.beerdrinkreminder.CounterService";

    private Handler handler = new Handler();

    AlcoholCalc alcCalc;

    //VARIABLES FOR THE CALCULATIONS
    double palamisVauhtiSekunissa;
    double promillet;
    private int aloitusLukema = 0;

    @Override
    public void onCreate() {
        super.onCreate();
        intent = new Intent(BROADCAST_ACTION);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
      //  intent = new Intent(BROADCAST_ACTION);
        aloitusLukema++;

        //THIS IS FOR CHECKING IF THE SERVICE IS STARTED FOR THE FIRST TIME. IF IT IS, THEN WE CONSTRUCT THE ALCOHOL CALCULATOR.

        if(aloitusLukema == 1){

            int kehonpaino = intent.getIntExtra("kehonpaino", 0);
            Toast.makeText(getApplicationContext(),""+kehonpaino,Toast.LENGTH_SHORT).show();

            double juomanKoko = intent.getDoubleExtra("juomankoko", 0.0);

            double juomanVahvuus = intent.getDoubleExtra("juomanvahvuus", 0.0);

            double juontiaika = (intent.getDoubleExtra("juontiaika", 0.0));

            String sukupuoli = intent.getStringExtra("sukupuoli");

            alcCalc = new AlcoholCalc(sukupuoli,
                    kehonpaino,
                    juomanVahvuus,
                    juontiaika,
                    juomanKoko);
            double palamisvauhtiTunnissa = kehonpaino / 10;

            palamisVauhtiSekunissa = palamisvauhtiTunnissa / 3600;

        }
       /*
        //THIS SECTION IS DONE IF THE USER PRESSES THE DRINK-BUTTON IN COUNTER ACVITIVY AND ADDS ANOTHER DRINK.
        else if (intent.getIntExtra("id", 0) != 0){

            double juomanKoko = intent.getDoubleExtra("juomankoko", 0.0);

            double juomanVahvuus = intent.getDoubleExtra("juomanvahvuus", 0.0);

            double juontiaika = (intent.getDoubleExtra("juontiaika", 0.0));

            alcCalc.drinkABeer(juomanKoko/10, juontiaika, juomanVahvuus);

        }
        */

        handler.removeCallbacks(sendUpdatesToUI);
        handler.postDelayed(sendUpdatesToUI, 1000);

        return START_STICKY;

    }

    private Runnable sendUpdatesToUI = new Runnable() {
        public void run() {
            AlcCalculations();
            handler.postDelayed(this, 1000);
        }
    };

    private void AlcCalculations() {

        //THIS IS FOR CALCULATING THE ALCOHOL LEVEL
        promillet = alcCalc.calculateCurrentBac(palamisVauhtiSekunissa);

        double aikaTunteina = (alcCalc.getGrammat() / palamisVauhtiSekunissa) / 3600;

        intent.putExtra("aika", aikaTunteina);
        intent.putExtra("promillet", promillet);
        intent.putExtra("grammat", alcCalc.getGrammat());
        sendBroadcast(intent);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        handler.removeCallbacks(sendUpdatesToUI);

    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}

The app runs well in OnPause State. When I close the app it shows some error message :-

11-14 04:59:15.149 3539-3539/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 java.lang.RuntimeException: Unable to start service com.mypackage.henri.beerdrinkreminder.CounterService@536765c8 with null: java.lang.NullPointerException
                                                     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2507)
                                                     at android.app.ActivityThread.access$1900(ActivityThread.java:130)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1292)
                                                     at android.os.Handler.dispatchMessage(Handler.java:99)
                                                     at android.os.Looper.loop(Looper.java:137)
                                                     at android.app.ActivityThread.main(ActivityThread.java:4745)
                                                     at java.lang.reflect.Method.invokeNative(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:511)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                                                     at dalvik.system.NativeStart.main(Native Method)
                                                  Caused by: java.lang.NullPointerException
                                                     at com.mypackage.henri.beerdrinkreminder.CounterService.onStartCommand(CounterService.java:46)
                                                     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2490)
                                                     at android.app.ActivityThread.access$1900(ActivityThread.java:130)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1292)
                                                     at android.os.Handler.dispatchMessage(Handler.java:99)
                                                     at android.os.Looper.loop(Looper.java:137)
                                                     at android.app.ActivityThread.main(ActivityThread.java:4745)
                                                     at java.lang.reflect.Method.invokeNative(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:511)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                                                     at dalvik.system.NativeStart.main(Native Method)
11-14 04:59:17.345 3539-3539/? I/Process: Sending signal. PID: 3539 SIG: 9

Body:
remove Toast from your service

Toast.makeText(getApplicationContext(),""+kehonpaino,Toast.LENGTH_SHORT).show();

An Service has a few limitations:
It can't interact directly with your user interface.


问:
UE4 - Application won’t run on Android tablet
So, I did a video-game in UE 4.8 and compiled it for Android.
   It’s a game for training mathematical abilities in first and second
   graders, using Android tablets. However, the game won’t run in the
   tablets we are using for the training program. After installing the
   APK, when I try to run the game, it immediately closes and a sign
   appears saying: “The application has stopped”.  I installed the
   application in other several android devices and it works fine (e.g.
   LG F60, Samsung Galaxy S5). However, I need to make it work for this
   particular tablet, because those are the ones we are using for the
   training program and we have like 80 of them. The tablet is a
   ProntoTec X1, these are the specs:

CPU: All winner A31s Quad Core-Cortex A7, 1.2GHZ;

OS: 4.4 KitKat;

RAM: 1G DDR3;

10.1-inch screen, 1024 x 600 Pixels

I’ve tried different things, like compiling an empty project, but is the same: it works on other devices, but not on these tablets. I also compiled the game using different API versions of the SDK and NDK, but that didn’t help either. These are the versions that I’m currently using: ndk-r10e, ant-1.9.6, jdk-1.7.0, sdk platform-19 (android studio 1.2.2).
Please, any suggestion is welcome. Thanks!

答: Take a look at the droid versions supported, also have a look at the droid permissions, I had this issue some time ago and the permissions is what did it for me.</p>


问:
What is the best way to convert a 2D string vector to a 2D int vector c++?
I am reading a matrix from a file, I am reading it into a string vector so I can preserve the leading 0s in the file. Now I want to apply some mathematical operations on the vector and so I want to copy it into a 2D int vector. I am new to using vectors and I saw there was a couple of examples for 1D vectors, but I am confused with 2D vectors.

```<code>std::vector< std::vector<string> > data;
std::vector< std::vector<int> > res;
std::ifstream f("input.txt", ios::binary);
std::string line;

while(std::getline(f,line))
{
  std::vector<string> line_data;
  std::istringstream iss(line);
  std::string value;
  while(iss >> value)
    {
        line_data.push_back(value);
}
  data.push_back(line_data);
}
</code>```

My code above read the file line by line as a string and wrote it to the 2D string vector named data. My goal is to copy 2D data vector to the 2D res vector, how do I proceed with that ?

input.txt is a square boolean matrix.
for instance

```<code>0101
1010
1100
0001
</code>```

edit:

As recommended I tried using the transform function and this is where I got to :

```<code>for (unsigned int i = 0; i < data.size(); ++i)
{   std::vector<int> temp_data;

    std::transform(data[i].begin(), data[i].end(),
            std::back_inserter(temp_data),
            [](const auto& element) {   return std::stoi(element); });
    res.push_back(temp_data);
}
</code>```

but I am getting an invalid use of auto error here, and I am not even sure this is right for 2D vectors.

答:
A simple solution is to use std::transform with a lambda that calls std::stoi.

Here's an example:

```<code>#include <string>
#include <vector>
#include <algorithm>

int main() {
    std::vector<std::string> vs = {"123", "456", "789"};
    std::vector<int> vi;
    std::transform(vs.begin(), vs.end(),
        std:back_inserter(vi),
        [](const auto& element) { return std::stoi(element); });
// 'vi' now contains the integers 123, 456, 789
}
</code>```

Body:
I am reading a matrix from a file, I am reading it into a string vector so I can preserve the leading 0s in the file. Now I want to apply some mathematical operations on the vector and so I want to copy it into a 2D int vector. I am new to using vectors and I saw there was a couple of examples for 1D vectors, but I am confused with 2D vectors.

std::vector< std::vector<string> > data;
std::vector< std::vector<int> > res;
std::ifstream f("input.txt", ios::binary);
std::string line;

while(std::getline(f,line))
{
  std::vector<string> line_data;
  std::istringstream iss(line);
  std::string value;
  while(iss >> value)
    {
        line_data.push_back(value);
}
  data.push_back(line_data);
}

My code above read the file line by line as a string and wrote it to the 2D string vector named data. My goal is to copy 2D data vector to the 2D res vector, how do I proceed with that ?

input.txt is a square boolean matrix.
for instance

0101
1010
1100
0001

edit:

As recommended I tried using the transform function and this is where I got to :

for (unsigned int i = 0; i < data.size(); ++i)
{   std::vector<int> temp_data;

    std::transform(data[i].begin(), data[i].end(),
            std::back_inserter(temp_data),
            [](const auto& element) {   return std::stoi(element); });
    res.push_back(temp_data);
}

but I am getting an invalid use of auto error here, and I am not even sure this is right for 2D vectors.

Body:
A simple solution is to use std::transform with a lambda that calls std::stoi.

Here's an example:

#include <string>
#include <vector>
#include <algorithm>

int main() {
    std::vector<std::string> vs = {"123", "456", "789"};
    std::vector<int> vi;
    std::transform(vs.begin(), vs.end(),
        std:back_inserter(vi),
        [](const auto& element) { return std::stoi(element); });
// 'vi' now contains the integers 123, 456, 789
}


问:
Running Google Cloud SQL Proxy on Raspberry
I'm getting an error while trying to connect raspberry running ubuntu mate to my Google Cloud SQL instance.

These are the step I did to install:

```<code>git clone https://github.com/GoogleCloudPlatform/cloudsql-proxy
cd cloudsql-proxy/
sudo sh download_proxy.sh
</code>```

My instance is configured this way (I deleted some characters in the image and in the code):

I didn't set the network because I'll be using proxy

Then I download into the same folder my JSON key.

```<code>wget https://drive.google.com/file/d/my_key.json
</code>```

And the start the proxy

```<code>sudo ./cloud_sql_proxy -instances=be   -     21:us-central1:be   =tcp:3306 \
                  -credential_file=./my_key.json &
</code>```

But I'm getting the error:

pi@pi:~/cloudsql-proxy$ ./cloud_sql_proxy: 1: ./cloud_sql_proxy:
  Syntax error: ")" unexpected

I've tried removing the .json and I was getting the same error before without credential, I think that the problem is in the setup.

My dir ls is:

Any help is appreciated :)

答:
Ok.

I'm sharing what I did to make it work, as David I don't know what version was I downloading.

I tried to avoid installing Go but it was the only way to get it installed.

```<code>sudo apt-get install golang-go
export GOPATH=$HOME/go
go get github.com/GoogleCloudPlatform/cloudsql-proxy/cmd/cloud_sql_proxy
cd $GOPATH/bin
wget your_key.json
sudo ./cloud_sql_proxy -instances=the_full_name_of_the_instance=tcp:3306 -credential_file=./your_key.json &
</code>```

But I was getting a error because I already have mysql running localy in the same port

So now I'm using a unix soquet

```<code>sudo ./cloud_sql_proxy -instances=the_full_name_of_the_instance -credential_file=./your_key.json &
</code>```

And then it's ready for connections :)

Thanks guys

Body:
I'm getting an error while trying to connect raspberry running ubuntu mate to my Google Cloud SQL instance.

These are the step I did to install:

git clone https://github.com/GoogleCloudPlatform/cloudsql-proxy
cd cloudsql-proxy/
sudo sh download_proxy.sh

My instance is configured this way (I deleted some characters in the image and in the code):

I didn't set the network because I'll be using proxy

Then I download into the same folder my JSON key.

wget https://drive.google.com/file/d/my_key.json

And the start the proxy

sudo ./cloud_sql_proxy -instances=be   -     21:us-central1:be   =tcp:3306 \
                  -credential_file=./my_key.json &

But I'm getting the error:

pi@pi:~/cloudsql-proxy$ ./cloud_sql_proxy: 1: ./cloud_sql_proxy:
  Syntax error: ")" unexpected

I've tried removing the .json and I was getting the same error before without credential, I think that the problem is in the setup.

My dir ls is:

Any help is appreciated :)

Body:
Ok.

I'm sharing what I did to make it work, as David I don't know what version was I downloading.

I tried to avoid installing Go but it was the only way to get it installed.

sudo apt-get install golang-go
export GOPATH=$HOME/go
go get github.com/GoogleCloudPlatform/cloudsql-proxy/cmd/cloud_sql_proxy
cd $GOPATH/bin
wget your_key.json
sudo ./cloud_sql_proxy -instances=the_full_name_of_the_instance=tcp:3306 -credential_file=./your_key.json &

But I was getting a error because I already have mysql running localy in the same port

So now I'm using a unix soquet

sudo ./cloud_sql_proxy -instances=the_full_name_of_the_instance -credential_file=./your_key.json &

And then it's ready for connections :)

Thanks guys


问:
Get variable value from the response of an HTTP Sampler to Beanshell PostProcessor
In HTTP Sampler,response I have a javascript variable

```<code>int a=1;
</code>```

I want to get the value of this 'a' in BeanShell Post Processor, How do I get it in JMeter?

答:
The easiest way you can add Regular Expression Extractor as a Post Processor

```<code>Regular Expression: int a=(\w+);
Template: $1$
Match No.: 1
</code>```

For Beanshell (or better JSR 223) Post processor you will have to "work" to get the regex:

```<code>import java.util.regex.Matcher;
import java.util.regex.Pattern;
String stringToSearch=prev.getResponseDataAsString();
Pattern p = Pattern.compile("int a=(\\w+)");
Matcher m = p.matcher(stringToSearch);
if (m.find()){
  vars.put("a", m.group(1));
}
</code>```

In this script I'm adding the value to variable a, which later can be called ${a}

Body:
In HTTP Sampler,response I have a javascript variable

int a=1;

I want to get the value of this 'a' in BeanShell Post Processor, How do I get it in JMeter?

Body:
The easiest way you can add Regular Expression Extractor as a Post Processor

Regular Expression: int a=(\w+);
Template: $1$
Match No.: 1

For Beanshell (or better JSR 223) Post processor you will have to "work" to get the regex:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
String stringToSearch=prev.getResponseDataAsString();
Pattern p = Pattern.compile("int a=(\\w+)");
Matcher m = p.matcher(stringToSearch);
if (m.find()){
  vars.put("a", m.group(1));
}

In this script I'm adding the value to variable a, which later can be called ${a}


答: By default a service runs on the main thread only. You will have to either handle new thread creation and handling in onStartCommand function of the service or use a IntentService which be default starts a new background thread. </p>

Title: I am trying to run my app in background . But service Class is not working in background


问:
Unable to run Testng Maven Project with TestComplete
I have one Maven Project that have TestNg Classes and it is running fine with eclipse. I want to run same project with TestComplete , perform all the prerequisites as defined under TestComplete integration. I have attached the screen shot of error that i am facing.

Please Help it is urgent.error.png

答:
Seems like your maven project test classes uses relative file paths for loading drivers or maybe some other configuration file.

FYI, when you are running a maven project test class from Testcomplete, your relative path reference changes to the TestComplete project folder (where .pjs file is located) . It is not the root folder where your pom.xml resides.

So you have to update those file paths references to TC project location. Move those guest project/files to TC project folder , if required.


问:
Create Django RESTful service for execute an algorithm
I need to implement a Django RESTful service where I can run an algorithm and get the result.

On the server I need to have a CSV file with the records for the algorithm. A service, let's say /train will allow me to train a Random Forest with the data in the CSV file, and finally another service /predict will receive the parameters and send me the result. The problem is that I have this running as a script on my computer and I don't know how to structure it for a web application.

I have already done RESTful APIs in Django but this problem is different I think.

I won't need models?

What about the serializers?

My idea is to send a GET request to /predict with the parameters needed for the Random Forest and return the algorithm result.

Any suggestions? Or a public repo with a similar problem?

答:
let say you have

train_view for '/train' with POST request.

result_view for /predict  with GET request

Do you need models ?

I think you need that since in request /predict you are going to apply logic on the data you have given in request /train, so create model.

Do you need serializers

Since you have model, you can write modelserializer


问:
Python: failed to write results in multiple files
I have a master draft text file which has the tags like PA, ST etc. My intention is to create a file for each tag and write the lines containing the tag in to the corresponding file. Here is my current python code

```<code>#!/usr/bin/python3
import sys
flnmc=sys.argv[1]

tags_dict={'PA':'Positive_Assertions','ST':'Self_improvement_Thought'\
,'TO':'TodO_task','WK':'WorK_todo','FN':'FuNny','CURRENT':'CURRENT'}

print(flnmc)

def grep_tags(tag):
  with open(flnmc,'r') as fc:
    for line in fc:
      if tag in line:
        print(line,end='')

grep_tags('WK')

fc=open(flnmc,'r')
for tag, s in tags_dict.items():
  f=open("%s.txt" %s,'w')
  for line in fc:
    if tag in line:
      f.write(line)
  f.close()
</code>```

Problems: grep_tags function is working fine printing the lines containing the tag of the master text file. Also all the required files are created. But when it comes to writing the grepped results to corresponding files, I found only first tag's results are written as required while other tag files are empty.

答:
Put the:
    fc=open(flnmc,'r')
statement inside the:
    for tag, s in tags_dict.items():
    ....
loop
i.e. You have to invoke the open statement each time or it goes 'stale'...</p>

```<code>...
grep_tags('WK')

#fc=open(flnmc,'r')
for tag, s in tags_dict.items():
    fc=open(flnmc,'r')
    f=open("%s.txt" %s,'w')
    for line in fc:
        if tag in line:
            f.write(line)
f.close()
</code>```

Body:
I have a master draft text file which has the tags like PA, ST etc. My intention is to create a file for each tag and write the lines containing the tag in to the corresponding file. Here is my current python code

#!/usr/bin/python3
import sys
flnmc=sys.argv[1]

tags_dict={'PA':'Positive_Assertions','ST':'Self_improvement_Thought'\
,'TO':'TodO_task','WK':'WorK_todo','FN':'FuNny','CURRENT':'CURRENT'}

print(flnmc)

def grep_tags(tag):
  with open(flnmc,'r') as fc:
    for line in fc:
      if tag in line:
        print(line,end='')

grep_tags('WK')

fc=open(flnmc,'r')
for tag, s in tags_dict.items():
  f=open("%s.txt" %s,'w')
  for line in fc:
    if tag in line:
      f.write(line)
  f.close()

Problems: grep_tags function is working fine printing the lines containing the tag of the master text file. Also all the required files are created. But when it comes to writing the grepped results to corresponding files, I found only first tag's results are written as required while other tag files are empty.

Body:
Put the:
    fc=open(flnmc,'r')
statement inside the:
    for tag, s in tags_dict.items():
    ....
loop
i.e. You have to invoke the open statement each time or it goes 'stale'...

...
grep_tags('WK')

#fc=open(flnmc,'r')
for tag, s in tags_dict.items():
    fc=open(flnmc,'r')
    f=open("%s.txt" %s,'w')
    for line in fc:
        if tag in line:
            f.write(line)
f.close()


问:
Graphics32 Simple drawing layer scaling
For a learning purpose, I am trying to build an application, that behaves basically the same way, as a Graphics32 example application "ImgView_Layers" and than I am making slight changes. Now I am stuck on a problem with simple drawing layers. I create one the same way, as in the sample app. Than in the PaintSimpleDrawingHandler, I am trying to draw some other shapes, than the default spiral. And here comes the problem. The "default" spiral, is being scaled with the image - when zoomed out, the spiral is being zoomed out and vice versa. When the layer size is changed, the size of the spiral is changed as well. If I draw anything else, it remains unchanged when zooming, or changing the size of the layer.

Here is an example of a diamond, square and a spiral. The spiral "works" fine, the rest does not.

```<code>procedure TfrmMain.PaintSimpleDrawingHandler(Sender: TObject; Buffer: TBitmap32);
var
  Cx, Cy: Single;
  W2, H2: Single;
  I: Integer;
  yy, xx, yyy, xxx: integer;
const
  CScale = 1 / 200;
begin
  if Sender is TPositionedLayer then
    with TPositionedLayer(Sender).GetAdjustedLocation do
    begin
      W2 := (Right - Left) * 0.5;
      H2 := (Bottom - Top) * 0.5;
      Cx:= Left + W2;
      Cy:= Top + H2;
      W2 := W2 * CScale;
      H2 := H2 * CScale;
      Buffer.PenColor := clGreen32;

    // square
      xx := Round(Cx + W2 - 10);
      yy := Round(Cy + H2 - 10);
      xxx := Round(Cx + W2 + 10);
      yyy := Round(Cy + H2 + 10);

      Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);
    ///square

    // diamond
      Buffer.MoveToF(Cx - 10, Cy);
      Buffer.LineToFS(Cx + W2, Cy + H2 - 10);
      Buffer.MoveToF(Cx, Cy - 10);
      Buffer.LineToFS(Cx + W2 + 10, Cy + H2);
      Buffer.MoveToF(Cx + 10, Cy);
      Buffer.LineToFS(Cx + W2, Cy + H2 + 10);
      Buffer.MoveToF(Cx, Cy + 10);
      Buffer.LineToFS(Cx + W2 - 10, Cy + H2);
    ///diamond

    // spiral
      Buffer.MoveToF(Cx, Cy);
      for I := 0 to 240 do
        Buffer.LineToFS(
          Cx + W2 * I * Cos(I * 0.125),
          Cy + H2 * I * Sin(I * 0.125));

    end;

end;
</code>```

I tried a few different shapes, different ways to draw them, but still get the same result. Can someone please try to explain the difference between the spiral and the rest, and help me to draw custom shapes, that will be zoomed and scaled the same way as the spiral?

I use Delphi XE7. Here is the complete source:

```<code>    unit Test;

interface
{$I GR32.inc}

uses
  Windows,
  Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, GR32_Image, Vcl.ExtCtrls,
  AdvToolBar, AdvShapeButton, AdvAppStyler, AdvToolBarStylers, AdvPreviewMenu,
  AdvPreviewMenuStylers, AdvPanel, DataModule, AdvGlassButton, Vcl.StdCtrls,
  AeroButtons, AdvGlowButton, GR32, GR32_Layers, GR32_RangeBars,
  GR32_Filters, GR32_Transforms, GR32_Resamplers, AdvTrackBar;

type
  TfrmMain = class(TForm)
    pnlMain: TPanel;
    AdvToolBarPager1: TAdvToolBarPager;
    AdvToolBarPager11: TAdvPage;
    AdvToolBarPager12: TAdvPage;
    AdvToolBarPager13: TAdvPage;
    pnlMainRight: TAdvPanel;
    pnlMainLeft: TAdvPanel;
    pnlMainCenter: TAdvPanel;
    AdvShapeButton1: TAdvShapeButton;
    pnlMainBottom: TAdvPanel;
    iwMain: TImgView32;
    btManImgPick: TAdvGlowButton;
    tbZoom: TAdvTrackBar;
    btZoom: TAdvGlowButton;
    btAddMark: TAdvGlowButton;
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure btManImgPickClick(Sender: TObject);
    procedure OpenImage(const FileName: string);
    procedure iwMainMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
    procedure iwMainMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
    procedure iwMainMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
    procedure iwMainResize(Sender: TObject);
    procedure tbZoomChange(Sender: TObject);
    procedure btZoomClick(Sender: TObject);
    procedure iwMainMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
    procedure iwMainMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
    procedure btAddMarkClick(Sender: TObject);
  private
    FSelection: TPositionedLayer;
    FDragging: Boolean;
    FFrom: TPoint;
    procedure SetSelection(Value: TPositionedLayer);
  public
    property Selection: TPositionedLayer read FSelection write SetSelection;
  protected
    RBLayer: TRubberbandLayer;
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
    procedure RBResizing(Sender: TObject; const OldLocation: TFloatRect;
      var NewLocation: TFloatRect; DragState: TRBDragState; Shift: TShiftState);
    procedure LayerDblClick(Sender: TObject);
    procedure iwAutofit;
    function CreatePositionedLayer: TPositionedLayer;
    procedure LayerMouseDown(Sender: TObject; Buttons: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure PaintSimpleDrawingHandler(Sender: TObject; Buffer: TBitmap32);
    procedure drawMark();
  end;

var
  frmTest: TfrmMain;
  DataModule: TDataModule;
implementation

{$R *.dfm}

uses
  JPEG,
  NewImageUnit, RGBALoaderUnit, Math, Printers, GR32_LowLevel, GR32_Paths,
  GR32_VectorUtils, GR32_Backends, GR32_Text_VCL, GR32_ColorGradients,
  GR32_Polygons, GR32_Geometry;

procedure TfrmMain.OpenImage(const FileName: string);
begin
  with iwMain do
  try
    Selection := nil;
    RBLayer := nil;
    Layers.Clear;
    Scale := 1;
    Bitmap.LoadFromFile(FileName);
  finally
    //pnlImage.Visible := not Bitmap.Empty;
  end;
end;

procedure TfrmMain.PaintSimpleDrawingHandler(Sender: TObject;
  Buffer: TBitmap32);
var
  Cx, Cy: Single;
  W2, H2: Single;
  I: Integer;
  yy, xx, yyy, xxx: integer;
const
  CScale = 1 / 200;
begin
  if Sender is TPositionedLayer then
    with TPositionedLayer(Sender).GetAdjustedLocation do
    begin
      W2 := (Right - Left) * 0.5;
      H2 := (Bottom - Top) * 0.5;
      Cx:= Left + W2;
      Cy:= Top + H2;
      W2 := W2 * CScale;
      H2 := H2 * CScale;
      Buffer.PenColor := clGreen32;

      xx := Round(Cx + W2 - 10);
      yy := Round(Cy + H2 - 10);
      xxx := Round(Cx + W2 + 10);
      yyy := Round(Cy + H2 + 10);

      Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);

      Buffer.MoveToF(Cx - 10, Cy);
      Buffer.LineToFS(Cx + W2, Cy + H2 - 10);
      Buffer.MoveToF(Cx, Cy - 10);
      Buffer.LineToFS(Cx + W2 + 10, Cy + H2);
      Buffer.MoveToF(Cx + 10, Cy);
      Buffer.LineToFS(Cx + W2, Cy + H2 + 10);
      Buffer.MoveToF(Cx, Cy + 10);
      Buffer.LineToFS(Cx + W2 - 10, Cy + H2);

      Buffer.MoveToF(Cx, Cy);
      for I := 0 to 240 do
        Buffer.LineToFS(
          Cx + W2 * I * Cos(I * 0.125),
          Cy + H2 * I * Sin(I * 0.125));

    end;
end;

procedure TfrmMain.RBResizing(Sender: TObject;
  const OldLocation: TFloatRect; var NewLocation: TFloatRect;
  DragState: TRBDragState; Shift: TShiftState);
var
  w, h, cx, cy: Single;
  nw, nh: Single;

begin
  if DragState = dsMove then Exit; // we are interested only in scale operations
  if Shift = [] then Exit; // special processing is not required

  if ssCtrl in Shift then
  begin
    { make changes symmetrical }

    with OldLocation do
    begin
      cx := (Left + Right) / 2;
      cy := (Top + Bottom) / 2;
      w := Right - Left;
      h := Bottom - Top;
    end;

    with NewLocation do
    begin
      nw := w / 2;
      nh := h / 2;
      case DragState of
        dsSizeL: nw := cx - Left;
        dsSizeT: nh := cy - Top;
        dsSizeR: nw := Right - cx;
        dsSizeB: nh := Bottom - cy;
        dsSizeTL: begin nw := cx - Left; nh := cy - Top; end;
        dsSizeTR: begin nw := Right - cx; nh := cy - Top; end;
        dsSizeBL: begin nw := cx - Left; nh := Bottom - cy; end;
        dsSizeBR: begin nw := Right - cx; nh := Bottom - cy; end;
      end;
      if nw < 2 then nw := 2;
      if nh < 2 then nh := 2;

      Left := cx - nw;
      Right := cx + nw;
      Top := cy - nh;
      Bottom := cy + nh;
    end;
  end;
end;

procedure TfrmMain.SetSelection(Value: TPositionedLayer);
begin
  if Value <> FSelection then
  begin
    if RBLayer <> nil then
    begin
      RBLayer.ChildLayer := nil;
      RBLayer.LayerOptions := LOB_NO_UPDATE;
      //pnlBitmapLayer.Visible := False;
      //pnlButtonMockup.Visible := False;
      //pnlMagnification.Visible := False;
      iwMain.Invalidate;
    end;

    FSelection := Value;

    if Value <> nil then
    begin
      if RBLayer = nil then
      begin
        RBLayer := TRubberBandLayer.Create(iwMain.Layers);
        RBLayer.MinHeight := 1;
        RBLayer.MinWidth := 1;
      end
      else
        RBLayer.BringToFront;
      RBLayer.ChildLayer := Value;
      RBLayer.LayerOptions := LOB_VISIBLE or LOB_MOUSE_EVENTS or LOB_NO_UPDATE;
      RBLayer.OnResizing := RBResizing;
      RBLayer.OnDblClick := LayerDblClick;

      if Value is TBitmapLayer then
        with TBitmapLayer(Value) do
        begin
          //pnlBitmapLayer.Visible := True;
          //GbrLayerOpacity.Position := Bitmap.MasterAlpha;
          //CbxLayerInterpolate.Checked := Bitmap.Resampler.ClassType = TDraftResampler;
        end
      else if Value.Tag = 2 then
      begin
        // tag = 2 for button mockup
        //pnlButtonMockup.Visible := True;
      end
      else if Value.Tag = 3 then
      begin
        // tag = 3 for magnifiers
        //pnlMagnification.Visible := True;
      end;
    end;
  end;
end;

procedure TfrmMain.tbZoomChange(Sender: TObject);
begin
  iwMain.Scale:= tbZoom.Position / 10;
  btZoom.Caption:= FloatToStr(tbZoom.Position / 10 * 100) + '%';
end;

procedure TfrmMain.btAddMarkClick(Sender: TObject);
begin
  drawMark();
end;

procedure TfrmMain.btManImgPickClick(Sender: TObject);
var jpg : TJPEGImage;
    //bcImage : TBacmedImage;
    //Center : Coordinant;
begin
  with DataModule1.OpenPictureDialog do
    if Execute then
    begin
      jpg:=TJPEGImage.Create;
      jpg.LoadFromFile(FileName);
      //Center.x:=round(jpg.Width/2);
      //Center.y:=round(jpg.Height/2);
      //bcImage:=TBacmedImage.Create(jpg,100,'AAA',1,Center,jpg.Width,23.83);
      OpenImage(FileName);
    end;
    iwAutofit();
end;

procedure TfrmMain.btZoomClick(Sender: TObject);
begin
  iwAutofit();
end;

function TfrmMain.CreatePositionedLayer: TPositionedLayer;
var
  P: TPoint;
begin
  // get coordinates of the center of viewport
  with iwMain.GetViewportRect do
    P := iwMain.ControlToBitmap(GR32.Point((Right + Left) div 2, (Top + Bottom) div 2));

  Result := TPositionedLayer.Create(iwMain.Layers);
  Result.Location := FloatRect(P.X - 32, P.Y - 32, P.X + 32, P.Y + 32);
  Result.Scaled := True;
  Result.MouseEvents := True;
  Result.OnMouseDown := LayerMouseDown;
  Result.OnDblClick := LayerDblClick;
end;

procedure TfrmMain.drawMark;
var
  L: TPositionedLayer;
begin
  L := CreatePositionedLayer;
  L.OnPaint := PaintSimpleDrawingHandler;
  L.Tag := 1;
  Selection := L;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  DataModule:= TDataModule.Create(self);
end;

procedure TfrmMain.FormResize(Sender: TObject);
begin
  //pnlMainRight.Width:= round(frmTest.Width / 5);
end;

procedure TfrmMain.iwAutofit;
begin
  if iwMain.Bitmap.Height > 0 then //jednoducha cesta jak checknout neprirazeny obrazek. Pokud je neprirazeny, nezoomovat.
  begin
    tbZoom.Position:= Round(iwMain.Height / iwMain.Bitmap.Height * 10);
    btZoom.Caption:= IntToStr(Round(iwMain.Height / iwMain.Bitmap.Height * 100)) + '%';
    iwMain.Scale:= iwMain.Height / iwMain.Bitmap.Height;
  end;
end;

procedure TfrmMain.iwMainMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
  if Button = mbMiddle then
  begin
    FDragging := True;
    iwMain.Cursor:= crDrag;
    FFrom := Point(X, Y);
  end;
end;

procedure TfrmMain.iwMainMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer; Layer: TCustomLayer);
begin
  if FDragging then
  begin
    iwMain.Scroll(FFrom.X - X, FFrom.Y - Y);
    FFrom.X:= X;
    FFrom.Y:= Y;
  end;

end;

procedure TfrmMain.iwMainMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
  if Button = mbMiddle then
  begin
    FDragging := False;
    iwMain.Cursor:= crDefault;
    iwMain.SetFocus;
  end;
end;

procedure TfrmMain.iwMainMouseWheelDown(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  tbZoom.Position:= tbZoom.Position - 1;
end;

procedure TfrmMain.iwMainMouseWheelUp(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  tbZoom.Position:= tbZoom.Position + 1;
end;

procedure TfrmMain.iwMainResize(Sender: TObject);
begin
  iwAutofit();
end;

procedure TfrmMain.LayerDblClick(Sender: TObject);
begin
  if Sender is TRubberbandLayer then
    TRubberbandLayer(Sender).Quantize;
end;

procedure TfrmMain.LayerMouseDown(Sender: TObject;
  Buttons: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Sender <> nil then Selection := TPositionedLayer(Sender);
end;

procedure TfrmMain.WMNCHitTest(var Message: TWMNCHitTest);
const
  EDGEDETECT = 7; // adjust
var
  deltaRect: TRect;
begin
  inherited;
  if BorderStyle = TFormBorderStyle(0) then
    with Message, deltaRect do
    begin
      Left := XPos - BoundsRect.Left;
      Right := BoundsRect.Right - XPos;
      Top := YPos - BoundsRect.Top;
      Bottom := BoundsRect.Bottom - YPos;
      if (Top < EDGEDETECT) and (Left < EDGEDETECT) then
        Result := HTTOPLEFT
      else if (Top < EDGEDETECT) and (Right < EDGEDETECT) then
        Result := HTTOPRIGHT
      else if (Bottom < EDGEDETECT) and (Left < EDGEDETECT) then
        Result := HTBOTTOMLEFT
      else if (Bottom < EDGEDETECT) and (Right < EDGEDETECT) then
        Result := HTBOTTOMRIGHT
      else if (Top < EDGEDETECT) then
        Result := HTTOP
      else if (Left < EDGEDETECT) then
        Result := HTLEFT
      else if (Bottom < EDGEDETECT) then
        Result := HTBOTTOM
      else if (Right < EDGEDETECT) then
        Result := HTRIGHT
    end;
end;

end.
</code>```

答:
If I draw anything else, it remains unchanged when zooming, or
  changing the size of the layer.

And that is because you don't change the size of your objects with the zooming or resizing:

```<code>  // square
  xx := Round(Cx + W2 - 10);
  yy := Round(Cy + H2 - 10);
  xxx := Round(Cx + W2 + 10);
  yyy := Round(Cy + H2 + 10);

  Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);
</code>```

The size of the rectangle is defined by the constants -10 and +10 (Cx+W2 and Cy+H2 defines the center point).
Try, for example, this instead:

```<code>  xx  := Round(Cx + W2 *(- 2));
  yy  := Round(Cy + H2 *(- 2));
  xxx := Round(Cx + W2 *(+ 2));
  yyy := Round(Cy + H2 *(+ 2));
</code>```

Title: Graphics32 Simple drawing layer scaling

Body:
For a learning purpose, I am trying to build an application, that behaves basically the same way, as a Graphics32 example application "ImgView_Layers" and than I am making slight changes. Now I am stuck on a problem with simple drawing layers. I create one the same way, as in the sample app. Than in the PaintSimpleDrawingHandler, I am trying to draw some other shapes, than the default spiral. And here comes the problem. The "default" spiral, is being scaled with the image - when zoomed out, the spiral is being zoomed out and vice versa. When the layer size is changed, the size of the spiral is changed as well. If I draw anything else, it remains unchanged when zooming, or changing the size of the layer.

Here is an example of a diamond, square and a spiral. The spiral "works" fine, the rest does not.

procedure TfrmMain.PaintSimpleDrawingHandler(Sender: TObject; Buffer: TBitmap32);
var
  Cx, Cy: Single;
  W2, H2: Single;
  I: Integer;
  yy, xx, yyy, xxx: integer;
const
  CScale = 1 / 200;
begin
  if Sender is TPositionedLayer then
    with TPositionedLayer(Sender).GetAdjustedLocation do
    begin
      W2 := (Right - Left) * 0.5;
      H2 := (Bottom - Top) * 0.5;
      Cx:= Left + W2;
      Cy:= Top + H2;
      W2 := W2 * CScale;
      H2 := H2 * CScale;
      Buffer.PenColor := clGreen32;

    // square
      xx := Round(Cx + W2 - 10);
      yy := Round(Cy + H2 - 10);
      xxx := Round(Cx + W2 + 10);
      yyy := Round(Cy + H2 + 10);

      Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);
    ///square

    // diamond
      Buffer.MoveToF(Cx - 10, Cy);
      Buffer.LineToFS(Cx + W2, Cy + H2 - 10);
      Buffer.MoveToF(Cx, Cy - 10);
      Buffer.LineToFS(Cx + W2 + 10, Cy + H2);
      Buffer.MoveToF(Cx + 10, Cy);
      Buffer.LineToFS(Cx + W2, Cy + H2 + 10);
      Buffer.MoveToF(Cx, Cy + 10);
      Buffer.LineToFS(Cx + W2 - 10, Cy + H2);
    ///diamond

    // spiral
      Buffer.MoveToF(Cx, Cy);
      for I := 0 to 240 do
        Buffer.LineToFS(
          Cx + W2 * I * Cos(I * 0.125),
          Cy + H2 * I * Sin(I * 0.125));

    end;

end;

I tried a few different shapes, different ways to draw them, but still get the same result. Can someone please try to explain the difference between the spiral and the rest, and help me to draw custom shapes, that will be zoomed and scaled the same way as the spiral?

I use Delphi XE7. Here is the complete source:

    unit Test;

interface
{$I GR32.inc}

uses
  Windows,
  Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, GR32_Image, Vcl.ExtCtrls,
  AdvToolBar, AdvShapeButton, AdvAppStyler, AdvToolBarStylers, AdvPreviewMenu,
  AdvPreviewMenuStylers, AdvPanel, DataModule, AdvGlassButton, Vcl.StdCtrls,
  AeroButtons, AdvGlowButton, GR32, GR32_Layers, GR32_RangeBars,
  GR32_Filters, GR32_Transforms, GR32_Resamplers, AdvTrackBar;

type
  TfrmMain = class(TForm)
    pnlMain: TPanel;
    AdvToolBarPager1: TAdvToolBarPager;
    AdvToolBarPager11: TAdvPage;
    AdvToolBarPager12: TAdvPage;
    AdvToolBarPager13: TAdvPage;
    pnlMainRight: TAdvPanel;
    pnlMainLeft: TAdvPanel;
    pnlMainCenter: TAdvPanel;
    AdvShapeButton1: TAdvShapeButton;
    pnlMainBottom: TAdvPanel;
    iwMain: TImgView32;
    btManImgPick: TAdvGlowButton;
    tbZoom: TAdvTrackBar;
    btZoom: TAdvGlowButton;
    btAddMark: TAdvGlowButton;
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure btManImgPickClick(Sender: TObject);
    procedure OpenImage(const FileName: string);
    procedure iwMainMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
    procedure iwMainMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
    procedure iwMainMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
    procedure iwMainResize(Sender: TObject);
    procedure tbZoomChange(Sender: TObject);
    procedure btZoomClick(Sender: TObject);
    procedure iwMainMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
    procedure iwMainMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
    procedure btAddMarkClick(Sender: TObject);
  private
    FSelection: TPositionedLayer;
    FDragging: Boolean;
    FFrom: TPoint;
    procedure SetSelection(Value: TPositionedLayer);
  public
    property Selection: TPositionedLayer read FSelection write SetSelection;
  protected
    RBLayer: TRubberbandLayer;
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
    procedure RBResizing(Sender: TObject; const OldLocation: TFloatRect;
      var NewLocation: TFloatRect; DragState: TRBDragState; Shift: TShiftState);
    procedure LayerDblClick(Sender: TObject);
    procedure iwAutofit;
    function CreatePositionedLayer: TPositionedLayer;
    procedure LayerMouseDown(Sender: TObject; Buttons: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure PaintSimpleDrawingHandler(Sender: TObject; Buffer: TBitmap32);
    procedure drawMark();
  end;

var
  frmTest: TfrmMain;
  DataModule: TDataModule;
implementation

{$R *.dfm}

uses
  JPEG,
  NewImageUnit, RGBALoaderUnit, Math, Printers, GR32_LowLevel, GR32_Paths,
  GR32_VectorUtils, GR32_Backends, GR32_Text_VCL, GR32_ColorGradients,
  GR32_Polygons, GR32_Geometry;

procedure TfrmMain.OpenImage(const FileName: string);
begin
  with iwMain do
  try
    Selection := nil;
    RBLayer := nil;
    Layers.Clear;
    Scale := 1;
    Bitmap.LoadFromFile(FileName);
  finally
    //pnlImage.Visible := not Bitmap.Empty;
  end;
end;

procedure TfrmMain.PaintSimpleDrawingHandler(Sender: TObject;
  Buffer: TBitmap32);
var
  Cx, Cy: Single;
  W2, H2: Single;
  I: Integer;
  yy, xx, yyy, xxx: integer;
const
  CScale = 1 / 200;
begin
  if Sender is TPositionedLayer then
    with TPositionedLayer(Sender).GetAdjustedLocation do
    begin
      W2 := (Right - Left) * 0.5;
      H2 := (Bottom - Top) * 0.5;
      Cx:= Left + W2;
      Cy:= Top + H2;
      W2 := W2 * CScale;
      H2 := H2 * CScale;
      Buffer.PenColor := clGreen32;

      xx := Round(Cx + W2 - 10);
      yy := Round(Cy + H2 - 10);
      xxx := Round(Cx + W2 + 10);
      yyy := Round(Cy + H2 + 10);

      Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);

      Buffer.MoveToF(Cx - 10, Cy);
      Buffer.LineToFS(Cx + W2, Cy + H2 - 10);
      Buffer.MoveToF(Cx, Cy - 10);
      Buffer.LineToFS(Cx + W2 + 10, Cy + H2);
      Buffer.MoveToF(Cx + 10, Cy);
      Buffer.LineToFS(Cx + W2, Cy + H2 + 10);
      Buffer.MoveToF(Cx, Cy + 10);
      Buffer.LineToFS(Cx + W2 - 10, Cy + H2);

      Buffer.MoveToF(Cx, Cy);
      for I := 0 to 240 do
        Buffer.LineToFS(
          Cx + W2 * I * Cos(I * 0.125),
          Cy + H2 * I * Sin(I * 0.125));

    end;
end;

procedure TfrmMain.RBResizing(Sender: TObject;
  const OldLocation: TFloatRect; var NewLocation: TFloatRect;
  DragState: TRBDragState; Shift: TShiftState);
var
  w, h, cx, cy: Single;
  nw, nh: Single;

begin
  if DragState = dsMove then Exit; // we are interested only in scale operations
  if Shift = [] then Exit; // special processing is not required

  if ssCtrl in Shift then
  begin
    { make changes symmetrical }

    with OldLocation do
    begin
      cx := (Left + Right) / 2;
      cy := (Top + Bottom) / 2;
      w := Right - Left;
      h := Bottom - Top;
    end;

    with NewLocation do
    begin
      nw := w / 2;
      nh := h / 2;
      case DragState of
        dsSizeL: nw := cx - Left;
        dsSizeT: nh := cy - Top;
        dsSizeR: nw := Right - cx;
        dsSizeB: nh := Bottom - cy;
        dsSizeTL: begin nw := cx - Left; nh := cy - Top; end;
        dsSizeTR: begin nw := Right - cx; nh := cy - Top; end;
        dsSizeBL: begin nw := cx - Left; nh := Bottom - cy; end;
        dsSizeBR: begin nw := Right - cx; nh := Bottom - cy; end;
      end;
      if nw < 2 then nw := 2;
      if nh < 2 then nh := 2;

      Left := cx - nw;
      Right := cx + nw;
      Top := cy - nh;
      Bottom := cy + nh;
    end;
  end;
end;

procedure TfrmMain.SetSelection(Value: TPositionedLayer);
begin
  if Value <> FSelection then
  begin
    if RBLayer <> nil then
    begin
      RBLayer.ChildLayer := nil;
      RBLayer.LayerOptions := LOB_NO_UPDATE;
      //pnlBitmapLayer.Visible := False;
      //pnlButtonMockup.Visible := False;
      //pnlMagnification.Visible := False;
      iwMain.Invalidate;
    end;

    FSelection := Value;

    if Value <> nil then
    begin
      if RBLayer = nil then
      begin
        RBLayer := TRubberBandLayer.Create(iwMain.Layers);
        RBLayer.MinHeight := 1;
        RBLayer.MinWidth := 1;
      end
      else
        RBLayer.BringToFront;
      RBLayer.ChildLayer := Value;
      RBLayer.LayerOptions := LOB_VISIBLE or LOB_MOUSE_EVENTS or LOB_NO_UPDATE;
      RBLayer.OnResizing := RBResizing;
      RBLayer.OnDblClick := LayerDblClick;

      if Value is TBitmapLayer then
        with TBitmapLayer(Value) do
        begin
          //pnlBitmapLayer.Visible := True;
          //GbrLayerOpacity.Position := Bitmap.MasterAlpha;
          //CbxLayerInterpolate.Checked := Bitmap.Resampler.ClassType = TDraftResampler;
        end
      else if Value.Tag = 2 then
      begin
        // tag = 2 for button mockup
        //pnlButtonMockup.Visible := True;
      end
      else if Value.Tag = 3 then
      begin
        // tag = 3 for magnifiers
        //pnlMagnification.Visible := True;
      end;
    end;
  end;
end;

procedure TfrmMain.tbZoomChange(Sender: TObject);
begin
  iwMain.Scale:= tbZoom.Position / 10;
  btZoom.Caption:= FloatToStr(tbZoom.Position / 10 * 100) + '%';
end;

procedure TfrmMain.btAddMarkClick(Sender: TObject);
begin
  drawMark();
end;

procedure TfrmMain.btManImgPickClick(Sender: TObject);
var jpg : TJPEGImage;
    //bcImage : TBacmedImage;
    //Center : Coordinant;
begin
  with DataModule1.OpenPictureDialog do
    if Execute then
    begin
      jpg:=TJPEGImage.Create;
      jpg.LoadFromFile(FileName);
      //Center.x:=round(jpg.Width/2);
      //Center.y:=round(jpg.Height/2);
      //bcImage:=TBacmedImage.Create(jpg,100,'AAA',1,Center,jpg.Width,23.83);
      OpenImage(FileName);
    end;
    iwAutofit();
end;

procedure TfrmMain.btZoomClick(Sender: TObject);
begin
  iwAutofit();
end;

function TfrmMain.CreatePositionedLayer: TPositionedLayer;
var
  P: TPoint;
begin
  // get coordinates of the center of viewport
  with iwMain.GetViewportRect do
    P := iwMain.ControlToBitmap(GR32.Point((Right + Left) div 2, (Top + Bottom) div 2));

  Result := TPositionedLayer.Create(iwMain.Layers);
  Result.Location := FloatRect(P.X - 32, P.Y - 32, P.X + 32, P.Y + 32);
  Result.Scaled := True;
  Result.MouseEvents := True;
  Result.OnMouseDown := LayerMouseDown;
  Result.OnDblClick := LayerDblClick;
end;

procedure TfrmMain.drawMark;
var
  L: TPositionedLayer;
begin
  L := CreatePositionedLayer;
  L.OnPaint := PaintSimpleDrawingHandler;
  L.Tag := 1;
  Selection := L;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  DataModule:= TDataModule.Create(self);
end;

procedure TfrmMain.FormResize(Sender: TObject);
begin
  //pnlMainRight.Width:= round(frmTest.Width / 5);
end;

procedure TfrmMain.iwAutofit;
begin
  if iwMain.Bitmap.Height > 0 then //jednoducha cesta jak checknout neprirazeny obrazek. Pokud je neprirazeny, nezoomovat.
  begin
    tbZoom.Position:= Round(iwMain.Height / iwMain.Bitmap.Height * 10);
    btZoom.Caption:= IntToStr(Round(iwMain.Height / iwMain.Bitmap.Height * 100)) + '%';
    iwMain.Scale:= iwMain.Height / iwMain.Bitmap.Height;
  end;
end;

procedure TfrmMain.iwMainMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
  if Button = mbMiddle then
  begin
    FDragging := True;
    iwMain.Cursor:= crDrag;
    FFrom := Point(X, Y);
  end;
end;

procedure TfrmMain.iwMainMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer; Layer: TCustomLayer);
begin
  if FDragging then
  begin
    iwMain.Scroll(FFrom.X - X, FFrom.Y - Y);
    FFrom.X:= X;
    FFrom.Y:= Y;
  end;

end;

procedure TfrmMain.iwMainMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
  if Button = mbMiddle then
  begin
    FDragging := False;
    iwMain.Cursor:= crDefault;
    iwMain.SetFocus;
  end;
end;

procedure TfrmMain.iwMainMouseWheelDown(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  tbZoom.Position:= tbZoom.Position - 1;
end;

procedure TfrmMain.iwMainMouseWheelUp(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  tbZoom.Position:= tbZoom.Position + 1;
end;

procedure TfrmMain.iwMainResize(Sender: TObject);
begin
  iwAutofit();
end;

procedure TfrmMain.LayerDblClick(Sender: TObject);
begin
  if Sender is TRubberbandLayer then
    TRubberbandLayer(Sender).Quantize;
end;

procedure TfrmMain.LayerMouseDown(Sender: TObject;
  Buttons: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Sender <> nil then Selection := TPositionedLayer(Sender);
end;

procedure TfrmMain.WMNCHitTest(var Message: TWMNCHitTest);
const
  EDGEDETECT = 7; // adjust
var
  deltaRect: TRect;
begin
  inherited;
  if BorderStyle = TFormBorderStyle(0) then
    with Message, deltaRect do
    begin
      Left := XPos - BoundsRect.Left;
      Right := BoundsRect.Right - XPos;
      Top := YPos - BoundsRect.Top;
      Bottom := BoundsRect.Bottom - YPos;
      if (Top < EDGEDETECT) and (Left < EDGEDETECT) then
        Result := HTTOPLEFT
      else if (Top < EDGEDETECT) and (Right < EDGEDETECT) then
        Result := HTTOPRIGHT
      else if (Bottom < EDGEDETECT) and (Left < EDGEDETECT) then
        Result := HTBOTTOMLEFT
      else if (Bottom < EDGEDETECT) and (Right < EDGEDETECT) then
        Result := HTBOTTOMRIGHT
      else if (Top < EDGEDETECT) then
        Result := HTTOP
      else if (Left < EDGEDETECT) then
        Result := HTLEFT
      else if (Bottom < EDGEDETECT) then
        Result := HTBOTTOM
      else if (Right < EDGEDETECT) then
        Result := HTRIGHT
    end;
end;

end.

Body:
If I draw anything else, it remains unchanged when zooming, or
  changing the size of the layer.

And that is because you don't change the size of your objects with the zooming or resizing:

  // square
  xx := Round(Cx + W2 - 10);
  yy := Round(Cy + H2 - 10);
  xxx := Round(Cx + W2 + 10);
  yyy := Round(Cy + H2 + 10);

  Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);

The size of the rectangle is defined by the constants -10 and +10 (Cx+W2 and Cy+H2 defines the center point).
Try, for example, this instead:

  xx  := Round(Cx + W2 *(- 2));
  yy  := Round(Cy + H2 *(- 2));
  xxx := Round(Cx + W2 *(+ 2));
  yyy := Round(Cy + H2 *(+ 2));